## 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 } } ]