00001 #!/usr/bin/perl
00002 # MythWeather-revamp script to retreive weather information from Environment
00003 # Canada.
00004 #
00005 # Most of this code was taken directly from Lucien Dunning's
00006 # (ldunning@gmail.com) PERL scripts. Kudos to Lucien for doing all of the
00007 # hard work that I shamelessly stole.
00008 #
00009
00010 use strict;
00011 use warnings;
00012
00013 use English;
00014 use File::Basename;
00015 use Cwd 'abs_path';
00016 use lib dirname(abs_path($0 or $PROGRAM_NAME)),
00017 '/usr/share/mythtv/mythweather/scripts/ca_envcan',
00018 '/usr/local/share/mythtv/mythweather/scripts/ca_envcan';
00019
00020 use LWP::Simple;
00021 use Date::Manip;
00022 use Getopt::Std;
00023 use ENVCANLocation;
00024 use ENVCANParser;
00025 use Data::Dumper;
00026
00027 our ($opt_v, $opt_t, $opt_T, $opt_l, $opt_u, $opt_d);
00028
00029 my $name = 'ENVCAN';
00030 my $version = 0.4;
00031 my $author = 'Joe Ripley';
00032 my $email = 'vitaminjoe@gmail.com';
00033 my $updateTimeout = 15*60;
00034 my $retrieveTimeout = 30;
00035 my @types = ('cclocation', 'station_id', 'copyright',
00036 'observation_time', 'observation_time_rfc822', 'weather',
00037 'temp', 'relative_humidity',
00038 'wind_dir', 'wind_degrees', 'wind_speed', 'wind_gust',
00039 'pressure', 'dewpoint', 'heat_index', 'windchill',
00040 'visibility', 'weather_icon', 'appt', 'wind_spdgst',
00041 '3dlocation', '6dlocation', 'date-0', 'icon-0', 'low-0', 'high-0',
00042 'date-1', 'icon-1', 'low-1', 'high-1',
00043 'date-2', 'icon-2', 'low-2', 'high-2', 'updatetime',
00044 'date-3', 'icon-3', 'low-3', 'high-3',
00045 'date-4', 'icon-4', 'low-4', 'high-4',
00046 'date-5', 'icon-5', 'low-5', 'high-5' );
00047
00048 my $dir = "./";
00049
00050 getopts('Tvtlu:d:');
00051
00052 if (defined $opt_v) {
00053 print "$name,$version,$author,$email\n";
00054 exit 0;
00055 }
00056
00057 if (defined $opt_T) {
00058 print "$updateTimeout,$retrieveTimeout\n";
00059 exit 0;
00060 }
00061 if (defined $opt_l) {
00062 my $search = shift;
00063 ENVCANLocation::AddStationIdSearch($search);
00064 ENVCANLocation::AddRegionIdSearch($search);
00065 ENVCANLocation::AddCitySearch($search);
00066 ENVCANLocation::AddProvinceSearch($search);
00067 my $results = doSearch();
00068 my $result;
00069 while($result = shift @$results) {
00070 if ($result->{station_id} ne "NA" ) {
00071 print "$result->{station_id}::";
00072 print "$result->{city}, $result->{region_id}\n";
00073 }
00074 }
00075 exit 0;
00076 }
00077
00078
00079 if (defined $opt_t) {
00080 foreach (@types) {print; print "\n";}
00081 exit 0;
00082 }
00083
00084 if (defined $opt_d) {
00085 $dir = $opt_d;
00086 }
00087
00088 # check variables for defined status
00089 my $loc = shift;
00090 if (!(defined $opt_u && defined $loc && !$loc eq "")) {
00091 die "Invalid usage";
00092 }
00093
00094 my $units = $opt_u;
00095
00096 # check for cached data
00097 my $creationdate;
00098 my $nextupdate;
00099 my %results;
00100 my $getData = 1;
00101 if (open(CACHE, "$dir/envcan_$loc")) {
00102 ($nextupdate, $creationdate) = split / /, <CACHE>;
00103 if (Date_Cmp($nextupdate, "now") > 0) { # use cache
00104 no strict "vars";
00105 %results = eval <CACHE>;
00106
00107 if (%results) { $getData = 0; }
00108 else { print STDERR "Error parsing cache $@\n"; }
00109 }
00110 }
00111 close(CACHE);
00112
00113 # no cache, grab from the web
00114 if ($getData) {
00115 my $base_url = 'http://www.weatheroffice.gc.ca/rss/city/';
00116 my $response = get $base_url . $loc .'_e.xml';
00117 die unless defined $response;
00118
00119 %results = ENVCANParser::doParse($response, @types);
00120 $results{'station_id'} = $loc;
00121
00122 # output cache
00123 open (CACHE, ">$dir/envcan_$loc") or
00124 die ("Cannot open cache ($dir/envcan_$loc) for writing.");
00125 $Data::Dumper::Purity = 1;
00126 $Data::Dumper::Indent = 0;
00127
00128 # cache is good for 15 minutes
00129 my $newmin = 15;
00130
00131 $nextupdate = DateCalc("now", "+ $newmin minutes");
00132 print CACHE UnixDate($nextupdate, "%O ") . UnixDate("now", "%O\n");
00133 print CACHE Data::Dumper->Dump([\%results], ['*results']);
00134 }
00135
00136 # do some quick conversions
00137 if ($units eq "ENG") {
00138 $results{'temp'} = int(((9/5) * $results{'temp'}) + 32);
00139 $results{'dewpoint'} = int(((9/5) * $results{'dewpoint'}) + 32);
00140 $results{'windchill'} = int(((9/5) * $results{'windchill'}) + 32);
00141 $results{'appt'} = int(((9/5) * $results{'appt'}) + 32);
00142 $results{'visibility'} = sprintf("%.1f", ($results{'visibility'} * 0.621371192));
00143 $results{'pressure'} = sprintf("%.2f", $results{'pressure'} * 0.0295301);
00144 $results{'wind_gust'} = sprintf("%.2f", $results{'wind_gust'} * 0.621371192);
00145 $results{'wind_speed'} = sprintf("%.2f", $results{'wind_speed'} * 0.621371192);
00146 $results{'wind_spdgst'} = sprintf("%.2f (%.2f)", $results{'wind_speed'}, $results{'wind_gust'});
00147
00148 for (my $i=0;$i<6;$i++) {
00149 if ($results{"high-$i"} =~ /\d*/) {
00150 $results{"high-$i"} = int(((9/5) * $results{"high-$i"}) + 32);
00151 }
00152 if ($results{"low-$i"} =~ /\d*/) {
00153 $results{"low-$i"} = int(((9/5) * $results{"low-$i"}) + 32);
00154 }
00155 }
00156 } else {
00157 $results{'wind_spdgst'} = sprintf("%.2f (%.2f)", $results{'wind_speed'}, $results{'wind_gust'});
00158 }
00159
00160
00161 foreach my $key (sort (keys %results)) {
00162 print "$key". "::";
00163 if (length($results{$key}) == 0) {
00164 print "NA\n";
00165 } else {
00166 print $results{$key} ."\n";
00167 }
00168 }
00169