## sample records probabilistically
next unless ( rand() > .95 ); # 1 of every 20
####
#!/usr/bin/env perl
use strict;
use warnings;
use DateTime::Format::Strptime;
use 5.016;
use Log::Log4perl;
use Mojo::UserAgent;
use open ':std', OUT => ':utf8';
use Mojo::Util qw(dumper);
use Astro::Coord::ECI;
use Astro::Coord::ECI::Sun;
use Astro::Coord::ECI::Utils qw{deg2rad rad2deg};
use Path::Tiny;
# get rid of old log
my $file = '/home/hogan/Documents/hogan/logs/4.log4perl.txt';
unlink $file or warn "Could not unlink $file: $!";
my $log_conf4 = "/home/hogan/Documents/hogan/logs/conf_files/4.conf";
Log::Log4perl::init($log_conf4); #info
my $logger = Log::Log4perl->get_logger();
$logger->info("$0");
## important...no trailing zeroes else 301 error
my $lat = 33.4;
my $long = -112.1;
my $elev = .346; #km
$logger->info("$lat $long $elev");
# Set up observer's location
my $loc = Astro::Coord::ECI->geodetic( deg2rad($lat), deg2rad($long), $elev );
my $url1 = "https://api.weather.gov/points/$lat,$long";
$logger->info("==============");
$logger->info("$url1");
# the API docs says you must identify yourself, please make this something legit
my $name = '(example.com, contact@example.com)';
my $ua = Mojo::UserAgent->new;
$ua->transactor->name($name);
# get JSON response
my $pv = $ua->get($url1)->res->json->{properties};
my $station = $pv->{'cwa'};
my $gridX = $pv->{'gridX'};
my $gridY = $pv->{'gridY'};
$logger->info("$station");
$logger->info("$gridX $gridY");
my $url =
"https://api.weather.gov/gridpoints/$station/$gridX,$gridY/forecast/hourly";
$logger->info("==============");
$logger->info("$url");
# the API docs says you must identify yourself, please make this something legit
$name = '(example.com, contact@example.com)';
$ua = Mojo::UserAgent->new;
$ua->transactor->name($name);
# get JSON response
my $forecasts = $ua->get($url)->res->json->{properties}->{periods};
use DateTime::Format::Strptime;
my $dateparser = DateTime::Format::Strptime->new(
# parses 2020-04-26T06:00:00-05:00,
# %F then literal T then %T then timezone offset
pattern => '%FT%T%z'
) or die "failed to DateTime::Format::Strptime->new()";
my @ordered;
my $refordered = \@ordered;
my $index = 0;
for my $aforecast (@$forecasts) {
## sample records probabilistically
next unless ( rand() > .95 ); # 1 of every 20
my $number = $aforecast->{number};
# start and end times of the prediction, convert them to objects
my $start_time_str = $aforecast->{'startTime'};
my $start_time_dateobj = $dateparser->parse_datetime($start_time_str)
or die "parsing date '$start_time_str'.";
my $jd = $start_time_dateobj->jd;
$start_time_dateobj->set_time_zone('America/Los_Angeles');
my $st = $start_time_dateobj->strftime('%Y-%m-%d-%H:%M:%S %Z');
my $hour = $start_time_dateobj->hour_12();
my $which_m = $start_time_dateobj->am_or_pm();
my $abrv = $start_time_dateobj->day_abbr();
# sunny?
my $forecast_str = $aforecast->{'shortForecast'};
# temperature as a number, see later for the units
my $temp = $aforecast->{'temperature'};
my $cloud_layers = $aforecast->{cloudLayers};
### using Astro::Coord::ECI::Sun
# Instantiate the Sun.
my $sun = Astro::Coord::ECI::Sun->universal( $start_time_dateobj->epoch() );
# Figure out if the Sun is up at the observer's location.
my ( $azimuth, $elevation, $range ) = $loc->azel($sun);
### using Your Sky fourmilab
my $west_long = -$long;
my $pturl =
'http://www.fourmilab.ch/cgi-bin/Yoursky?z=1&lat=$lat&ns=North&lon=$west_long&ew=West';
# you wanted Julian date so it looks like date should be '2' from the source.
my $tx = $ua->post( $pturl => form => { utc => $jd, date => '2' } );
my $sunrow =
$tx->res->dom->at('center:nth-of-type(3) table tr:nth-of-type(3)');
my $alt2 = $sunrow->children->[4]->text;
say 'Altitude: ' . $sunrow->children->[4]->text;
my $az2 = $sunrow->children->[5]->text;
say 'Azimuth: ' . $sunrow->children->[5]->text;
my $vis = $sunrow->children->[6]->text;
# new scope for hash
my %parsed;
# store this record/prediction in our %parsed hash
# keyed on this:
my $key = $start_time_str;
$parsed{$key} = {
"Sun degrees above horizon" => rad2deg($elevation),
'azimuth' => rad2deg($azimuth),
'human-readable' => "$abrv $hour $which_m",
'cloud layers' => $cloud_layers,
'date-from-local' => $st,
'number' => $number,
'forecast-string' => $forecast_str,
'julian day' => $jd,
'Altitude: ' => $alt2,
'Azimuth: ' => $az2,
'Visible: ' => $vis,
# we append temp unit to the key, e.g. 'F'
'forecast-temp-' . $aforecast->{'temperatureUnit'} => $temp,
};
my $refparsed = \%parsed;
$ordered[$index] = $refparsed;
#$logger->info( dumper $refparsed);
++$index;
}
$logger->info( dumper $refordered);
__END__
####
2020/05/29 18:07:49 INFO ./4.5.pho.pl
2020/05/29 18:07:49 INFO 33.4 -112.1 0.346
2020/05/29 18:07:49 INFO ==============
2020/05/29 18:07:49 INFO https://api.weather.gov/points/33.4,-112.1
2020/05/29 18:07:49 INFO PSR
2020/05/29 18:07:49 INFO 157 55
2020/05/29 18:07:49 INFO ==============
2020/05/29 18:07:49 INFO https://api.weather.gov/gridpoints/PSR/157,55/forecast/hourly
2020/05/29 18:07:52 INFO [
{
"2020-05-29T21:00:00-07:00" => {
"Altitude: " => "\x{2212}17.703",
"Azimuth: " => "\x{2212}156.087",
"Sun degrees above horizon" => "-16.1346147595787",
"Visible: " => "Set",
"azimuth" => "310.872811707612",
"cloud layers" => undef,
"date-from-local" => "2020-05-29-21:00:00 PDT",
"forecast-string" => "Mostly Clear",
"forecast-temp-F" => 99,
"human-readable" => "Fri 9 PM",
"julian day" => "2458999.66666667",
"number" => 4
}
},
{
"2020-05-30T18:00:00-07:00" => {
"Altitude: " => "\x{2212}17.703",
"Azimuth: " => "\x{2212}156.087",
"Sun degrees above horizon" => "17.1340319222249",
"Visible: " => "Set",
"azimuth" => "285.418507531741",
"cloud layers" => undef,
"date-from-local" => "2020-05-30-18:00:00 PDT",
"forecast-string" => "Clear",
"forecast-temp-F" => 105,
"human-readable" => "Sat 6 PM",
"julian day" => "2459000.54166667",
"number" => 25
}
},
{
"2020-06-01T18:00:00-07:00" => {
"Altitude: " => "\x{2212}17.703",
"Azimuth: " => "\x{2212}156.087",
"Sun degrees above horizon" => "17.3283178854741",
"Visible: " => "Set",
"azimuth" => "285.624647720491",
"cloud layers" => undef,
"date-from-local" => "2020-06-01-18:00:00 PDT",
"forecast-string" => "Partly Cloudy",
"forecast-temp-F" => 104,
"human-readable" => "Mon 6 PM",
"julian day" => "2459002.54166667",
"number" => 73
}
},
{
"2020-06-02T12:00:00-07:00" => {
"Altitude: " => "\x{2212}17.701",
"Azimuth: " => "\x{2212}156.084",
"Sun degrees above horizon" => "77.4732937742126",
"Visible: " => "Set",
"azimuth" => "150.511216157841",
"cloud layers" => undef,
"date-from-local" => "2020-06-02-12:00:00 PDT",
"forecast-string" => "Mostly Sunny",
"forecast-temp-F" => 101,
"human-readable" => "Tue 12 PM",
"julian day" => "2459003.29166667",
"number" => 91
}
},
{
"2020-06-03T05:00:00-07:00" => {
"Altitude: " => "\x{2212}17.701",
"Azimuth: " => "\x{2212}156.084",
"Sun degrees above horizon" => "-4.30877305256147",
"Visible: " => "Set",
"azimuth" => "59.5078006913088",
"cloud layers" => undef,
"date-from-local" => "2020-06-03-05:00:00 PDT",
"forecast-string" => "Partly Cloudy",
"forecast-temp-F" => 80,
"human-readable" => "Wed 5 AM",
"julian day" => 2459004,
"number" => 108
}
},
{
"2020-06-03T08:00:00-07:00" => {
"Altitude: " => "\x{2212}17.701",
"Azimuth: " => "\x{2212}156.084",
"Sun degrees above horizon" => "31.0652801390284",
"Visible: " => "Set",
"azimuth" => "82.1673527295036",
"cloud layers" => undef,
"date-from-local" => "2020-06-03-08:00:00 PDT",
"forecast-string" => "Mostly Sunny",
"forecast-temp-F" => 88,
"human-readable" => "Wed 8 AM",
"julian day" => "2459004.125",
"number" => 111
}
},
{
"2020-06-03T09:00:00-07:00" => {
"Altitude: " => "\x{2212}17.701",
"Azimuth: " => "\x{2212}156.084",
"Sun degrees above horizon" => "43.537502398186",
"Visible: " => "Set",
"azimuth" => "89.779629384787",
"cloud layers" => undef,
"date-from-local" => "2020-06-03-09:00:00 PDT",
"forecast-string" => "Sunny",
"forecast-temp-F" => 92,
"human-readable" => "Wed 9 AM",
"julian day" => "2459004.16666667",
"number" => 112
}
},
{
"2020-06-03T20:00:00-07:00" => {
"Altitude: " => "\x{2212}17.700",
"Azimuth: " => "\x{2212}156.080",
"Sun degrees above horizon" => "-5.44783053937081",
"Visible: " => "Set",
"azimuth" => "301.52083115685",
"cloud layers" => undef,
"date-from-local" => "2020-06-03-20:00:00 PDT",
"forecast-string" => "Mostly Clear",
"forecast-temp-F" => 96,
"human-readable" => "Wed 8 PM",
"julian day" => "2459004.625",
"number" => 123
}
}
]