From 53c19406a53882298d663ab8ac8e91dd65e3cb58 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Sun, 15 Jul 2012 22:43:32 +0100 Subject: [PATCH] Add an 18 hour view for the UK Met Office grabber --- .../scripts/uk_metoffice/MetOffCommon.pm | 34 ++- .../uk_metoffice/metoffice_fivedayapi.pl | 14 +- .../uk_metoffice/metoffice_threehourapi.pl | 207 ++++++++++++++++++ 3 files changed, 249 insertions(+), 6 deletions(-) create mode 100755 mythplugins/mythweather/mythweather/scripts/uk_metoffice/metoffice_threehourapi.pl diff --git a/mythplugins/mythweather/mythweather/scripts/uk_metoffice/MetOffCommon.pm b/mythplugins/mythweather/mythweather/scripts/uk_metoffice/MetOffCommon.pm index 5670329e2dc..2b4d495fd26 100644 --- a/mythplugins/mythweather/mythweather/scripts/uk_metoffice/MetOffCommon.pm +++ b/mythplugins/mythweather/mythweather/scripts/uk_metoffice/MetOffCommon.pm @@ -11,10 +11,11 @@ use encoding 'utf8'; use LWP::UserAgent; use LWP::Simple; use XML::Simple; +use POSIX qw(strftime); #use Data::Dumper; -our @EXPORT = qw(Search FindLoc); +our @EXPORT = qw(Search convert_temp convert_speed time_format); our @EXPORT_OK = qw($apikey $copyrightstr $copyrightlogo $forecast_url); our $VERSION = 0.1; @@ -89,5 +90,36 @@ sub log_print { close OF; } +sub convert_temp { + my ( $degC, $units ) = @_; + my $deg; + + if( $units ne "SI" ) { + $deg = int(($degC * 1.8) + 32.5); # °F + } else { + $deg = $degC; + } + return $deg; +} + +sub convert_speed { + my ( $mph, $units ) = @_; + + my $speed; + + if( $units eq "SI") { + $speed = int($mph * 1.609344); # kph + } else { + $speed = $mph; + } + return $speed; +} + +sub format_date { + my ($time) = @_; + + return strftime '%a %e %b, %H:%M', localtime($time); +} + 1; diff --git a/mythplugins/mythweather/mythweather/scripts/uk_metoffice/metoffice_fivedayapi.pl b/mythplugins/mythweather/mythweather/scripts/uk_metoffice/metoffice_fivedayapi.pl index 5cc4a92655a..9a33b5ec9be 100755 --- a/mythplugins/mythweather/mythweather/scripts/uk_metoffice/metoffice_fivedayapi.pl +++ b/mythplugins/mythweather/mythweather/scripts/uk_metoffice/metoffice_fivedayapi.pl @@ -29,7 +29,7 @@ our ($opt_v, $opt_t, $opt_T, $opt_l, $opt_u, $opt_d, $opt_D); my $name = 'MetOffice-Forecast-API'; -my $version = 0.1; +my $version = 0.3; my $author = 'Stuart Morgan'; my $email = 'smorgan@mythtv.org'; @@ -92,6 +92,11 @@ exit 0; } +my $units = "SI"; +if (defined $opt_u) { + $units = $opt_u; +} + my $locid = shift; # we get here, we're doing an actual retrieval, everything must be defined #my $locid = MetOffLocation::FindLoc(shift, $dir, $updateInterval, $logdir); @@ -99,7 +104,6 @@ die "Invalid usage"; } -my $units = $opt_u; my $base_args = '?res=daily&key=' . $MetOffCommon::api_key; my $url = ""; @@ -128,7 +132,7 @@ my $location = $xml->{DV}->{Location}->{name}; printf "3dlocation::" . $location . "\n"; printf "6dlocation::" . $location . "\n"; -printf "updatetime::Updated " . localtime() . "\n"; +printf "updatetime::" . localtime() . "\n"; my $i = 0; my $item; @@ -184,8 +188,8 @@ printf "icon-" . $i . "::" . $iconname . ".png\n"; - printf "low-" . $i . "::" . $nighttime->{Nm} . "\n"; - printf "high-" . $i . "::" . $daytime->{Dm} . "\n"; + printf "low-" . $i . "::" . MetOffCommon::convert_temp($nighttime->{Nm}, $units) . "\n"; + printf "high-" . $i . "::" . MetOffCommon::convert_temp($daytime->{Dm}, $units) . "\n"; $i++; } diff --git a/mythplugins/mythweather/mythweather/scripts/uk_metoffice/metoffice_threehourapi.pl b/mythplugins/mythweather/mythweather/scripts/uk_metoffice/metoffice_threehourapi.pl new file mode 100755 index 00000000000..aa3396c7ab0 --- /dev/null +++ b/mythplugins/mythweather/mythweather/scripts/uk_metoffice/metoffice_threehourapi.pl @@ -0,0 +1,207 @@ +#! /usr/bin/perl +# vim:ts=4:sw=4:ai:et:si:sts=4 + +use strict; +use warnings; + +use utf8; +use encoding 'utf8'; +use English; + +use File::Basename; +use Cwd 'abs_path'; +use lib dirname(abs_path($0 or $PROGRAM_NAME)), + '/usr/share/mythtv/mythweather/scripts/uk_metoffice', + '/usr/local/share/mythtv/mythweather/scripts/uk_metoffice'; + +use XML::Simple; +use LWP::Simple; +use Getopt::Std; +use File::Path; +use Switch; + +use Date::Parse; +use Date::Calc qw(Day_of_Week); +use DateTime::Format::ISO8601; +use File::Basename; +use lib dirname($0); +use MetOffCommon qw(:DEFAULT $apikey); + +our ($opt_v, $opt_t, $opt_T, $opt_l, $opt_u, $opt_d, $opt_D); + +my $name = 'MetOffice-3Hourly-API'; +my $version = 0.3; +my $author = 'Stuart Morgan'; +my $email = 'smorgan@mythtv.org'; + +my $updateInterval = 3*60*60; # 3 Hours +my $retrieveTimeout = 30; +my @types = ('18hrlocation', + 'time-0', 'time-1', 'time-2', 'time-3', 'time-4', 'time-5', + '18icon-0', '18icon-1', '18icon-2', '18icon-3', '18icon-4', '18icon-5', + 'temp-0', 'temp-1', 'temp-2', 'temp-3', 'temp-4', 'temp-5', + 'pop-0', 'pop-1', 'pop-2', 'pop-3', 'pop-4', 'pop-5', + 'updatetime', 'copyright', 'copyrightlogo'); + +my $dir = "/tmp/uk_metoffice"; +my $logdir = "/tmp/uk_metoffice"; + +binmode(STDOUT, ":utf8"); + +if (!-d $logdir) { + mkpath( $logdir, {mode => 0755} ); +} + +getopts('Tvtlu:d:'); + +if (defined $opt_v) { + print "$name,$version,$author,$email\n"; + log_print( $logdir, "-v\n" ); + exit 0; +} + +if (defined $opt_T) { + print "$updateInterval,$retrieveTimeout\n"; + log_print( $logdir, "-t\n" ); + exit 0; +} + +if (defined $opt_d) { + $dir = $opt_d; +} + +if (!-d $dir) { + mkpath( $dir, {mode => 0755} ); +} + +if (defined $opt_l) { + my $search = shift; + log_print( $logdir, "-l $search\n" ); + my @results = MetOffCommon::Search($search, $dir, $updateInterval, $logdir); + my $result; + + foreach (@results) { + print $_ . "\n"; + } + + exit 0; +} + +if (defined $opt_t) { + foreach (@types) {print; print "\n";} + exit 0; +} + +my $units = "SI"; +if (defined $opt_u) { + $units = $opt_u; +} + +my $locid = shift; +# we get here, we're doing an actual retrieval, everything must be defined +#my $locid = MetOffLocation::FindLoc(shift, $dir, $updateInterval, $logdir); +if (!(defined $locid && !$locid eq "")) { + die "Invalid usage"; +} + +my $base_args = '?res=3hourly&key=' . $MetOffCommon::api_key; +my $url = ""; + +if ($locid =~ s/^(\d*)/$1/) +{ + $url = $MetOffCommon::forecast_url . $1 . $base_args; +} +else +{ + die "Invalid Location ID"; +} + + +my $response = get $url; +die unless defined $response; + +my $xml = XMLin($response); + +if (!$xml) { + die "Not xml"; +} + +printf "copyright::" . $MetOffCommon::copyright_str . "\n"; +printf "copyrightlogo::" . $MetOffCommon::copyright_logo . "\n"; +printf "station_id::" . $locid . "\n"; +my $location = $xml->{DV}->{Location}->{name}; +printf "18hrlocation::" . $location . "\n"; +printf "updatetime::" . localtime() . "\n"; + +my $item; +my $i = 0; + +foreach $item (@{$xml->{DV}->{Location}->{Period}}) { + + foreach my $rep (@{$item->{Rep}}) { + + my $datetime = DateTime::Format::ISO8601->parse_datetime(substr($item->{val}, 0, -1)); + $datetime->add( minutes => $rep->{content} ); + printf "time-" . $i . "::" . MetOffCommon::format_date($datetime->epoch) . "\n"; + my $iconname = "unknown"; + switch ($rep->{W}) { # Weather Type + case 0 { $iconname = "fair"; } # Clear sky + case 1 { $iconname = "sunny"; } # Sunny + case 2 { $iconname = "pcloudy"; } # Partly cloudy (night) + case 3 { $iconname = "pcloudy"; } # Sunny intervals + case 4 { $iconname = "dusthaze"; } # Dust + case 5 { $iconname = "fog"; } # Mist + case 6 { $iconname = "fog"; } # Fog + case 7 { $iconname = "mcloudy"; } # Medium-level cloud + case 8 { $iconname = "cloudy"; } # Low-level cloud + case 9 { $iconname = "lshowers"; } # Light rain shower (night) + case 10 { $iconname = "lshowers"; } # Light rain shower (day) + case 11 { $iconname = "lshowers"; } # Drizzle + case 12 { $iconname = "lshowers"; } # Light rain + case 13 { $iconname = "showers"; } # Heavy rain shower (night) + case 14 { $iconname = "showers"; } # Heavy rain shower (day) + case 15 { $iconname = "showers"; } # Heavy rain + case 16 { $iconname = "rainsnow"; } # Sleet shower (night) + case 17 { $iconname = "rainsnow"; } # Sleet shower (day) + case 18 { $iconname = "rainsnow"; } # Sleet + case 19 { $iconname = "rainsnow"; } # Hail shower (night) + case 20 { $iconname = "rainsnow"; } # Hail shower (day) + case 21 { $iconname = "rainsnow"; } # Hail + case 22 { $iconname = "flurries"; } # Light snow shower (night) + case 23 { $iconname = "flurries"; } # Light snow shower (day) + case 24 { $iconname = "flurries"; } # Light snow + case 25 { $iconname = "snowshow"; } # Heavy snow shower (night) + case 26 { $iconname = "snowshow"; } # Heavy snow shower (day) + case 27 { $iconname = "snowshow"; } # Heavy snow + case 28 { $iconname = "thunshowers"; } # Thundery shower (night) + case 29 { $iconname = "thunshowers"; } # Thundery shower (day) + case 30 { $iconname = "thunshowers"; } # Thunder storm + case 31 { $iconname = "thunshowers"; } # Tropical storm + case 33 { $iconname = "dusthaze"; } # Haze + } + + printf "weather_type" . $i . "::" . $rep->{W} . "\n"; + printf "18icon-" . $i . "::" . $iconname . ".png\n"; + printf "temp-" . $i . "::" . MetOffCommon::convert_temp($rep->{T}, $units) . "\n"; + printf "appt-" . $i . "::" . MetOffCommon::convert_temp($rep->{F}, $units) . "\n"; + printf "pop-" . $i . "::" . $rep->{Pp} . "\n"; + printf "wind_speed-" . $i . "::" . MetOffCommon::convert_speed($rep->{S}, $units) . "\n"; + printf "wind_gust-" . $i . "::" . MetOffCommon::convert_speed($rep->{G}, $units) . "\n"; + printf "wind_dir-" . $i . "::" . $rep->{D} . "\n"; + printf "relative_humidity-" . $i . "::" . $rep->{H} . "\n"; + printf "uv-" . $i . "::" . $rep->{U} . "\n"; + # printf "visibility-" . $i . "::" . $rep->{V} . "\n"; + + $i++; + } + +} + +sub log_print { + return if not defined $::opt_D; + my $dir = shift; + + open OF, ">>$dir/uk_metoffice.log"; + print OF @_; + close OF; +}