You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
3.9 KiB

<?php
namespace p3k;
use Config;
use DateTime, DateTimeZone;
class Weather {
public static function weather_for_location($lat, $lng, $key) {
if($key == 'XXX') {
return ['error' => 'Please provide an api key from openweathermap.org'];
}
$data = self::_fetch($lat, $lng, $key);
if(!$data) return null;
if(!property_exists($data, 'weather'))
return null;
$weather = [
'description' => null,
'icon' => [
'name' => null
],
'temp' => null,
'feelslike' => null,
'humidity' => null,
'wind' => null,
'pressure' => null,
'precip_today' => null,
'timezone' => [
'offset' => null,
'name' => null,
'abbr' => null
]
];
$sunny = self::_sunny($data->coord->lat, $data->coord->lon);
$icon_name = self::_icon_name($data->weather[0]->id);
$weather['sun'] = $sunny;
$weather['description'] = $data->weather[0]->description;
$weather['icon']['name'] = $icon_name;
$weather['temp'] = [
'num' => (double)$data->main->temp,
'unit' => '°F'
];
$weather['feelslike'] = [
'num' => (double)$data->main->feels_like,
'unit' => '°F'
];
$weather['wind'] = [
'num' => $data->wind->speed,
'unit' => 'mph'
];
$weather['pressure'] = [
'num' => (int)$data->main->pressure,
'unit' => 'mb'
];
$weather['humidity'] = [
'num' => round($data->main->humidity),
'unit' => '%'
];
$tz = new DateTimeZone($data->timezone);
$now = new DateTime();
$now->setTimeZone($tz);
$offset = $now->format('Z')/3600;
$weather['timezone']['name'] = $sunny['timezone'];
$weather['timezone']['offset'] = $offset;
#$weather['raw'] = $current;
return $weather;
}
private static function _fetch($lat, $lng, $key) {
$params = [
'units' => 'imperial',
'lat' => $lat,
'lon' => $lng,
'appid' => $key,
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.openweathermap.org/data/2.5/weather?'.http_build_query($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
// curl_setopt($ch, CURLOPT_USERAGENT, '');
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
$result = curl_exec($ch);
if($result == FALSE)
return FALSE;
return json_decode($result);
}
// Returns "day" or "night" depending on whether the sun is up at the given location
private static function _sunny($lat, $lng, $timezone=null) {
// Get the beginning of the current day
$now = new DateTime();
if(!$timezone) {
$timezone = \p3k\Timezone::timezone_for_location($lat, $lng);
}
$tz = new DateTimeZone($timezone);
$now->setTimeZone($tz);
$offset = $now->format('Z')/3600;
$now = $now->format('H') + ($now->format('i')/60);
$sunrise = date_sunrise($now, SUNFUNCS_RET_DOUBLE, $lat, $lng, 90, $offset);
$sunset = date_sunset($now, SUNFUNCS_RET_DOUBLE, $lat, $lng, 90, $offset);
return [
'sunrise' => round($sunrise,2),
'sunset' => round($sunset,2),
'now' => round($now,2),
'light' => ($sunrise < $now && $now < $sunset) ? 'day' : 'night',
'timezone' => $timezone,
];
}
private static function _icon_name($icon) {
return 'wi-owm-'.$icon;
/*
// A mapping of darksky to weather-icons is here https://erikflowers.github.io/weather-icons/api-list.html
$map = [
'clear-day' => 'day-sunny',
'clear-night' => 'night-clear',
'rain' => 'rain',
'snow' => 'snow',
'sleet' => 'sleet',
'wind' => 'strong-wind',
'fog' => 'day-haze',
'cloudy' => 'cloudy',
'partly-cloudy-day' => 'day-cloudy',
'partly-cloudy-night' => 'night-cloudy',
'hail' => 'day-hail',
'thunderstorm' => 'thunderstorm',
'tornado' => 'tornado',
];
if(array_key_exists($icon, $map)) {
return 'wi-'.$map[$icon];
} else {
return false;
}
*/
}
}