00001 #! /usr/bin/perl -w
00002
00003 use strict;
00004 use XML::Simple;
00005 use LWP::Simple;
00006 use Data::Dumper;
00007 use Getopt::Std;
00008 use NWSLocation;
00009
00010 our ($opt_v, $opt_t, $opt_T, $opt_l, $opt_u, $opt_d);
00011
00012 my $name = 'NWS-XML';
00013 my $version = 0.2;
00014 my $author = 'Lucien Dunning';
00015 my $email = 'ldunning@gmail.com';
00016 my $updateTimeout = 15*60;
00017 my $retrieveTimeout = 30;
00018 my @types = ('cclocation', 'station_id', 'latitude', 'longitude',
00019 'observation_time', 'observation_time_rfc822', 'weather',
00020 'temperature_string', 'temp', 'relative_humidity', 'wind_string',
00021 'wind_dir', 'wind_degrees', 'wind_speed', 'wind_gust',
00022 'pressure_string', 'pressure', 'dewpoint_string', 'dewpoint',
00023 'heat_index_string', 'heat_index', 'windchill_string', 'windchill',
00024 'visibility', 'weather_icon', 'appt', 'wind_spdgst');
00025 my $dir = "./";
00026
00027 getopts('Tvtlu:d:');
00028
00029 if (defined $opt_v) {
00030 print "$name,$version,$author,$email\n";
00031 exit 0;
00032 }
00033
00034 if (defined $opt_T) {
00035 print "$updateTimeout,$retrieveTimeout\n";
00036 exit 0;
00037 }
00038 if (defined $opt_l) {
00039 my $search = shift;
00040 NWSLocation::AddLocSearch($search);
00041 NWSLocation::AddStateSearch($search);
00042 NWSLocation::AddStationIdSearch($search);
00043 my $results = doSearch();
00044 my $result;
00045 while($result = shift @$results) {
00046 if ($result->{latitude} ne "NA" && $result->{longitude} ne "NA") {
00047 print "$result->{station_id}::";
00048 print "$result->{station_name}, $result->{state}\n";
00049 }
00050 }
00051
00052 exit 0;
00053
00054 }
00055
00056 if (defined $opt_t) {
00057 foreach (@types) {print; print "\n";}
00058 exit 0;
00059 }
00060
00061 if (defined $opt_d) {
00062 $dir = $opt_d;
00063 }
00064
00065
00066 # we get here, we're doing an actual retrieval, everything must be defined
00067 my $loc = shift;
00068 if (!(defined $opt_u && defined $loc && !$loc eq "")) {
00069 die "Invalid usage";
00070 }
00071
00072 my $units = $opt_u;
00073
00074 my $base_url = 'http://www.weather.gov/data/current_obs/';
00075
00076 my $response = get $base_url . $loc . '.xml';
00077 die unless defined $response;
00078
00079 my $xml = XMLin($response);
00080 foreach (@types) {
00081 my $label;
00082 my $key;
00083
00084 $label = $_;
00085
00086 if (/temp$/ || /dewpoint$/ || /heat_index$/ || /windchill$/) {
00087 $key = $_ . '_f' if $units =~ /ENG/;
00088 $key = $_ . '_c' if $units =~ /SI/;
00089 }
00090 elsif (/pressure$/) {
00091 $key = $_ . '_in' if $units =~ /ENG/;
00092 $key = $_ . '_mb' if $units =~ /SI/;
00093 }
00094 elsif (/wind_speed/) {
00095 if ($units =~ /ENG/) {
00096 $key = 'wind_mph';
00097 } else {
00098 $key = 'wind_kph';
00099 $xml->{$key} = int($xml->{'wind_mph'} * 1.609344 + .5);
00100 }
00101 } elsif (/wind_gust/) {
00102 if ($units =~ /ENG/ || $xml->{'wind_gust_mph'} eq 'NA') {
00103 $key = 'wind_gust_mph';
00104 } else {
00105 $key = 'wind_gust_kph';
00106 $xml->{$key} = int($xml->{'wind_gust_mph'} * 1.609344 + .5);
00107 }
00108 } elsif (/visibility/) {
00109 if ($units =~ /ENG/) {
00110 $key = 'visibility_mi';
00111 } else {
00112 $key = 'visibility_km';
00113 $xml->{$key} = int($xml->{'visibility_mi'} * 1.609344 + .5);
00114 }
00115 } elsif (/weather_icon/) {
00116 $key = 'weather_icon';
00117 $xml->{$key} = 'unknown.png';
00118 local *FH;
00119 open(FH, "icons") or die "Cannot open icons";
00120 while(my $line = <FH>) {
00121 chomp $line;
00122 if ($line =~ /$xml->{'icon_url_name'}::/) {
00123 $line =~ s/.*::
00124 $xml->{$key} = $line;
00125 last;
00126 }
00127 }
00128 } elsif (/cclocation/) {
00129 $key = 'location';
00130 } elsif (/appt$/) {
00131 if ($xml->{windchill_f} eq 'NA') {
00132 $key = 'heat_index_f' if ($units =~ /ENG/);
00133 $key = 'heat_index_c' if ($units =~ /SI/);
00134 } else {
00135 $key = 'windchill_f' if ($units =~ /ENG/);
00136 $key = 'windchill_c' if ($units =~ /SI/);
00137 };
00138
00139 } elsif (/wind_spdgst/) {
00140 # relying on this being after speed and gust
00141 $key = "wind_spdgst";
00142 if ($units =~ /ENG/ ) {
00143 $xml->{$key} = "$xml->{wind_mph} ($xml->{wind_gust_mph}) mph";
00144 } else {
00145 $xml->{$key} = "$xml->{wind_kph} ($xml->{wind_gust_kph}) kph";
00146 }
00147
00148 } else {
00149 $key = $label;
00150 }
00151 printf $label . "::" . $xml->{$key}. "\n";
00152 }