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