mirror of
https://github.com/jlu5/SupyPlugins.git
synced 2025-05-05 09:50:54 -05:00
NuWeather: switch to OneCall API for OpenWeatherMap
This API is more complete and includes things like daily forecasts.
This commit is contained in:
parent
47b7b422e4
commit
1eb83ea9df
@ -1,6 +1,6 @@
|
|||||||
###
|
###
|
||||||
# Copyright (c) 2011-2014, Valentin Lorentz
|
# Copyright (c) 2011-2014, Valentin Lorentz
|
||||||
# Copyright (c) 2018-2019, James Lu <james@overdrivenetworks.com>
|
# Copyright (c) 2018-2020, James Lu <james@overdrivenetworks.com>
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
@ -180,6 +180,8 @@ class NuWeather(callbacks.Plugin):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _format_uv(uv):
|
def _format_uv(uv):
|
||||||
|
if uv is None:
|
||||||
|
return _('N/A')
|
||||||
# From https://en.wikipedia.org/wiki/Ultraviolet_index#Index_usage 2018-12-30
|
# From https://en.wikipedia.org/wiki/Ultraviolet_index#Index_usage 2018-12-30
|
||||||
uv = float(uv)
|
uv = float(uv)
|
||||||
if uv <= 2.9:
|
if uv <= 2.9:
|
||||||
@ -503,71 +505,56 @@ class NuWeather(callbacks.Plugin):
|
|||||||
if not latlon:
|
if not latlon:
|
||||||
raise callbacks.Error("Unknown location %s." % location)
|
raise callbacks.Error("Unknown location %s." % location)
|
||||||
|
|
||||||
lat, lon, __, ___, geocode_backend = latlon
|
lat, lon, display_name, _geocode_id, geocode_backend = latlon
|
||||||
url = 'https://api.openweathermap.org/data/2.5/weather?' + utils.web.urlencode({
|
url = 'https://api.openweathermap.org/data/2.5/onecall?' + utils.web.urlencode({
|
||||||
'appid': apikey,
|
'appid': apikey,
|
||||||
'lat': lat,
|
'lat': lat,
|
||||||
'lon': lon,
|
'lon': lon,
|
||||||
'units': 'imperial',
|
'units': 'imperial',
|
||||||
})
|
})
|
||||||
self.log.debug('NuWeather: using url %s (current data)', url)
|
self.log.debug('NuWeather: using url %s', url)
|
||||||
|
|
||||||
f = utils.web.getUrl(url, headers=HEADERS).decode('utf-8')
|
f = utils.web.getUrl(url, headers=HEADERS).decode('utf-8')
|
||||||
data = json.loads(f, strict=False)
|
data = json.loads(f, strict=False)
|
||||||
|
|
||||||
|
currentdata = data['current']
|
||||||
|
|
||||||
|
# XXX: are the units for this consistent across APIs?
|
||||||
|
if currentdata.get('snow'):
|
||||||
|
precip = self._format_precip(mm=currentdata['snow']['1h'] * 10)
|
||||||
|
elif currentdata.get('rain'):
|
||||||
|
precip = self._format_precip(mm=currentdata['rain']['1h'])
|
||||||
|
else:
|
||||||
|
precip = 'N/A'
|
||||||
|
|
||||||
output = {
|
output = {
|
||||||
'location': '%s, %s' % (data['name'], data['sys']['country']),
|
'location': display_name,
|
||||||
'poweredby': 'OpenWeatherMap+' + geocode_backend,
|
'poweredby': 'OpenWeatherMap+' + geocode_backend,
|
||||||
'url': 'https://openweathermap.org/weathermap?' + utils.web.urlencode({
|
'url': 'https://openweathermap.org/weathermap?' + utils.web.urlencode({
|
||||||
'lat': lat,
|
'lat': lat,
|
||||||
'lon': lon,
|
'lon': lon,
|
||||||
'zoom': 12
|
'zoom': 12
|
||||||
}),
|
}),
|
||||||
# Unfortunately not all of the fields we use are available
|
|
||||||
'current': {
|
'current': {
|
||||||
'condition': data['weather'][0]['description'],
|
'condition': currentdata['weather'][0]['description'],
|
||||||
'temperature': self._format_temp(f=data['main']['temp']),
|
'temperature': self._format_temp(f=currentdata['temp']),
|
||||||
'feels_like': 'N/A',
|
'feels_like': self._format_temp(f=currentdata['feels_like']),
|
||||||
'humidity': self._format_percentage(data['main']['humidity']),
|
'humidity': self._format_percentage(currentdata['humidity']),
|
||||||
'precip': 'N/A',
|
'precip': precip,
|
||||||
'wind': self._format_distance(mi=data['wind']['speed'], speed=True),
|
'wind': self._format_distance(mi=currentdata['wind_speed'], speed=True),
|
||||||
'wind_gust': 'N/A',
|
'wind_dir': self._wind_direction(currentdata['wind_deg']),
|
||||||
'wind_dir': self._wind_direction(data['wind']['deg']),
|
'wind_gust': self._format_distance(mi=currentdata.get('wind_gust'), speed=True),
|
||||||
'uv': 'N/A', # Requires a separate API call
|
'uv': self._format_uv(currentdata.get('uvi')),
|
||||||
'visibility': self._format_distance(km=data['visibility']/1000),
|
'visibility': self._format_distance(km=currentdata['visibility']/1000),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tzoffset = data['timezone']
|
|
||||||
|
|
||||||
# Get extended forecast (a separate API call)
|
|
||||||
url = 'https://api.openweathermap.org/data/2.5/forecast?' + utils.web.urlencode({
|
|
||||||
'appid': apikey,
|
|
||||||
'lat': lat,
|
|
||||||
'lon': lon,
|
|
||||||
'units': 'imperial',
|
|
||||||
})
|
|
||||||
self.log.debug('NuWeather: using url %s (extended forecast)', url)
|
|
||||||
|
|
||||||
f = utils.web.getUrl(url, headers=HEADERS).decode('utf-8')
|
|
||||||
data = json.loads(f, strict=False)
|
|
||||||
def _owm_make_dayname(utcts):
|
|
||||||
# OWM gives timestamps in UTC, but the /weather endpoint provides a timezone
|
|
||||||
# offset in seconds. Use this data with pendulum to generate a human readable time.
|
|
||||||
ts = utcts + tzoffset
|
|
||||||
|
|
||||||
if pendulum:
|
|
||||||
dt = pendulum.from_timestamp(ts)
|
|
||||||
return dt.format('dddd hA') # Return strings like "Sunday 8PM"
|
|
||||||
return ts # fallback
|
|
||||||
|
|
||||||
# OWM's 5 day forecast gives data by 3 hour intervals. The actual daily forecast
|
|
||||||
# requires a subscription.
|
|
||||||
output['forecast'] = [
|
output['forecast'] = [
|
||||||
{'dayname': _owm_make_dayname(forecast['dt']),
|
{'dayname': self._get_dayname(forecast['dt'], idx, tz=data['timezone']),
|
||||||
'max': self._format_temp(f=forecast['main']['temp_max']),
|
'max': self._format_temp(f=forecast['temp']['max']),
|
||||||
'min': self._format_temp(f=forecast['main']['temp_min']),
|
'min': self._format_temp(f=forecast['temp']['min']),
|
||||||
'summary': forecast['weather'][0]['description']}
|
'summary': forecast['weather'][0]['description']}
|
||||||
for forecast in data['list'][1::2] # grab data every 6 hours, excluding first pocket
|
for idx, forecast in enumerate(data['daily'])
|
||||||
]
|
]
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user