You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
2.8 KiB
Python
77 lines
2.8 KiB
Python
import datetime
|
|
import os.path
|
|
|
|
import requests
|
|
|
|
|
|
def get_weather_json(lat, lon):
|
|
"""
|
|
fetches weather from the Norwegian meteorological institute
|
|
for a given latitude and longitude. Returns an object with a
|
|
3-day forecast with morning, afternoon, evening and overnight
|
|
periods. NOTE: This is not tidied up. Use get_forecast for
|
|
nicer formatted stuff.
|
|
"""
|
|
url = "https://api.met.no/weatherapi/locationforecast/2.0/complete"
|
|
headers = { "User-Agent": "https://gitlab.com/bhowell/the-screenless-office" }
|
|
# the 2.0+ api only allows a max resolution of four decimals (for cacheing)
|
|
params = { "lat": format(lat, ".4"), "lon": format(lon, ".4")}
|
|
|
|
# https://api.met.no/weatherapi/locationforecast/2.0/classic?lat=52.50639&lon=13.4063
|
|
resp = requests.get(url=url, params=params, headers=headers)
|
|
return resp.json()
|
|
|
|
def get_forecast(lat, lon):
|
|
"""
|
|
returns a list of forecast dicts:
|
|
forecast = { "fromtime": datetime, "totime": datetime,
|
|
"symbol": "pathto.svg", "mintemp": "12.7",
|
|
"maxtemp": "16.8", "period": "Morning"}
|
|
"""
|
|
thisdir = os.path.dirname(os.path.abspath(__file__))
|
|
periods = {6: "Morning", 12: "Afternoon", 18: "Evening", 0: "Overnight"}
|
|
|
|
# Berlin - "52.5", "13.4"
|
|
w = get_weather_json(lat, lon)
|
|
|
|
forecasts = []
|
|
for t in w["properties"]["timeseries"]:
|
|
# need to strip the trainling 'Z' char which indicates UTC
|
|
tdate = datetime.datetime.fromisoformat(t["time"][:-1])
|
|
to = tdate + datetime.timedelta(hours=6)
|
|
dtdelta = datetime.date.today() - tdate.date()
|
|
|
|
if dtdelta == datetime.timedelta(days=0):
|
|
day_of = "Today"
|
|
elif dtdelta == datetime.timedelta(days=-1):
|
|
day_of = "Tomorrow"
|
|
else:
|
|
days = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")
|
|
day_of = days[tdate.weekday()]
|
|
|
|
if tdate.hour not in (0, 6, 12, 18):
|
|
continue
|
|
|
|
if not("next_6_hours" in t["data"]):
|
|
continue
|
|
|
|
mintemp = t["data"]["next_6_hours"]["details"]["air_temperature_min"]
|
|
maxtemp = t["data"]["next_6_hours"]["details"]["air_temperature_max"]
|
|
symbol = t["data"]["next_6_hours"]["summary"]["symbol_code"]
|
|
png = symbol
|
|
symbol += ".svg"
|
|
png += ".png"
|
|
icon = os.path.join(thisdir, "weather_icons", symbol)
|
|
png = os.path.join(thisdir, "weather_icons", png)
|
|
forecast = {"fromtime": tdate, "totime": to, "symbol": icon,
|
|
"mintemp": mintemp, "maxtemp": maxtemp, "png": png,
|
|
"period": periods[tdate.hour], "day": day_of}
|
|
forecasts.append(forecast)
|
|
|
|
return forecasts
|
|
|
|
|
|
if __name__ == "__main__":
|
|
from pprint import pprint
|
|
pprint(get_forecast("52.5","13.4"))
|