weather: Restore darkskyapi through openweathermap
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
3449f1a828
commit
b3f79020f4
6
main.py
6
main.py
@ -104,11 +104,7 @@ def main(only_on_coming_evt=False, ignore_module=[], force_coming_event=True, ex
|
||||
if occuped_space < 250:
|
||||
# weekly weather
|
||||
from modules.weather import WeeklyWeatherModule
|
||||
shape.append(WidgetPlacement(WeeklyWeatherModule, size=(int(480/1.6), 165), position=(480-int(480/1.6), NEXT_STOP_Y + occuped_space + (5 if occuped_space else 0))))
|
||||
|
||||
# air quality
|
||||
from modules.weather import WeatherAirQualityModule
|
||||
shape.append(WidgetPlacement(WeatherAirQualityModule, size=(int(480/1.6), 100), position=(480-int(480/1.6), NEXT_STOP_Y + 165 + occuped_space + (5 if occuped_space else 0))))
|
||||
shape.append(WidgetPlacement(WeeklyWeatherModule, size=(int(480/1.6), 265), position=(480-int(480/1.6), NEXT_STOP_Y + occuped_space + (5 if occuped_space else 0))))
|
||||
|
||||
# RATP weather
|
||||
major_lines = ["M7", "M14", "RB", "TT3A"]
|
||||
|
@ -51,7 +51,6 @@ def draw_format_array(infos, width, height, fnt_R, fnt_B, label_margin, align_he
|
||||
title_hsize = 0
|
||||
text_hsize = 0
|
||||
for k,v in infos.items():
|
||||
print(fnt_R.getbbox(k))
|
||||
_,_,ksize,ksizeH = fnt_R.getbbox(k)
|
||||
_,_,vsize,vsizeH = fnt_B.getbbox(v)
|
||||
if title_hsize < ksizeH:
|
||||
@ -96,10 +95,10 @@ class WeatherToolbarModule:
|
||||
weather = WeatherAPI().get_currently()
|
||||
|
||||
infos = {
|
||||
"Vent": "%d km/h" % weather["wind_kph"],
|
||||
"Vent": "%d km/h" % weather["wind_speed"],
|
||||
"Humidité": "%d%%" % (weather["humidity"]),
|
||||
"Indice UV": str(int(weather["uv"])),
|
||||
"Pression": "%d hPa" % weather["pressure_mb"],
|
||||
"Indice UV": str(int(weather["uvi"])),
|
||||
"Pression": "%s hPa" % weather["pressure"],
|
||||
}
|
||||
|
||||
txt = draw_format_infos(infos, width, height, fnt_R, fnt_B, self.label_margin, align_height=height/2, anchor="lm")
|
||||
@ -123,21 +122,21 @@ class WeatherJumboCurrentModule:
|
||||
# current
|
||||
curweather = WeatherAPI().get_currently()
|
||||
|
||||
icon = Image.open(os.path.join(config.icons_dir, "weather", WeatherAPI.get_icon(curweather["condition"]["code"], night=not curweather["is_day"], current=True))).resize((height, height))
|
||||
icon = Image.open(os.path.join(config.icons_dir, "weather", WeatherAPI.get_icon(curweather["weather"][0]["id"], night=curweather["weather"][0]["icon"].endswith("n"), current=True))).resize((height, height))
|
||||
image.paste(icon, (int(width*self.middle_align - height), 0), icon)
|
||||
|
||||
draw.text(
|
||||
(width*self.middle_align, height/3),
|
||||
"%d˚ %s." % (math.trunc(curweather["temp_c"]), curweather["condition"]["text"]),
|
||||
"%d˚ %s." % (math.trunc(curweather["temp"]), curweather["weather"][0]["description"]),
|
||||
fill="black", anchor="ld", font=fnt_Big
|
||||
)
|
||||
|
||||
thisdayweather = list(itertools.islice(WeatherAPI().get_daily(), 1))[0]
|
||||
|
||||
infos = {
|
||||
"Ressentie": "%d˚" % curweather["feelslike_c"],
|
||||
"Minimale": "%d˚" % thisdayweather["mintemp_c"],
|
||||
"Maximale": "%d˚" % thisdayweather["maxtemp_c"],
|
||||
"Ressentie": "%d˚" % curweather["feels_like"],
|
||||
"Minimale": "%d˚" % thisdayweather["temp"]["min"],
|
||||
"Maximale": "%d˚" % thisdayweather["temp"]["max"],
|
||||
}
|
||||
|
||||
txt = draw_format_infos(infos, (1-self.middle_align) * width, 20, fnt_R, fnt_B, 5, margin_bf_first=False, fill="black", anchor="lt")
|
||||
@ -148,10 +147,10 @@ class WeatherJumboCurrentModule:
|
||||
|
||||
dayweather = list(itertools.islice(WeatherAPI().get_hourly(), 2))
|
||||
|
||||
if dayweather[0]["condition"]["text"] != dayweather[1]["condition"]["text"]:
|
||||
display_longtext(draw, (width*self.middle_align, height/1.28), dayweather[1]["condition"]["text"] + " la prochaine heure.\n" + thisdayweather["condition"]["text"] + " aujourd'hui.", fill="black", anchor="lm", font=fnt_Rig, maxwidth=(1-self.middle_align)*width)
|
||||
if dayweather[0]["weather"][0]["description"] != dayweather[1]["weather"][0]["description"]:
|
||||
display_longtext(draw, (width*self.middle_align, height/1.28), dayweather[1]["weather"][0]["description"] + " la prochaine heure.\n" + thisdayweather["summary"] + ".", fill="black", anchor="lm", font=fnt_Rig, maxwidth=(1-self.middle_align)*width)
|
||||
else:
|
||||
display_longtext(draw, (width*self.middle_align, height/1.28), thisdayweather["condition"]["text"] + " aujourd'hui", fill="black", anchor="lm", font=fnt_Rig, maxwidth=(1-self.middle_align)*width)
|
||||
display_longtext(draw, (width*self.middle_align, height/1.28), thisdayweather["summary"] + ".", fill="black", anchor="lm", font=fnt_Rig, maxwidth=(1-self.middle_align)*width)
|
||||
|
||||
return image
|
||||
|
||||
@ -177,8 +176,8 @@ class WeatherSunModule:
|
||||
|
||||
import time
|
||||
infos = {
|
||||
"sunrise": thisdayweather["sunrise"],
|
||||
"sunset": thisdayweather["sunset"],
|
||||
"sunrise": WeatherAPI().read_timestamp(thisdayweather["sunrise"]),
|
||||
"sunset": WeatherAPI().read_timestamp(thisdayweather["sunset"]),
|
||||
}
|
||||
|
||||
align = start_align
|
||||
@ -190,10 +189,10 @@ class WeatherSunModule:
|
||||
align += height + 2
|
||||
draw.text(
|
||||
(align, height / 2),
|
||||
info,
|
||||
str(info),
|
||||
fill="black", anchor="lm", font=fnt_R
|
||||
)
|
||||
align += fnt_R.getlength(info)
|
||||
align += fnt_R.getlength(str(info))
|
||||
align += 10
|
||||
|
||||
return image
|
||||
@ -211,24 +210,18 @@ class WeatherRainModule:
|
||||
percent_formatter = lambda x: '{:.10g}%'.format(x)
|
||||
gauge.value_formatter = percent_formatter
|
||||
|
||||
if thisdayweather["daily_chance_of_snow"] > 0:
|
||||
gauge.add('Neige', [{'value': thisdayweather["daily_chance_of_snow"] + 1}])
|
||||
icon_path = "wi-snowflake-cold.png"
|
||||
elif thisdayweather["daily_chance_of_rain"] > 0:
|
||||
gauge.add('Pluie', [{'value': thisdayweather["daily_chance_of_rain"] + 1}])
|
||||
if "gust_kph" in thisdayweather and thisdayweather["gust_kph"] > 45:
|
||||
if thisdayweather["pop"] > 0:
|
||||
gauge.add('Pluie', [{'value': thisdayweather["pop"] * 100}])
|
||||
if "wind_gust" in thisdayweather and thisdayweather["wind_gust"] > 45:
|
||||
icon_path = "wi-wind-beaufort-6.png"
|
||||
else:
|
||||
icon_path = "wi-umbrella.png"
|
||||
elif thisdayweather["uv"] > 4:
|
||||
gauge.add('Index UV', [{'value': thisdayweather["uv"] * 10}])
|
||||
elif thisdayweather["uvi"] > 4:
|
||||
gauge.add('Index UV', [{'value': thisdayweather["uvi"] * 10}])
|
||||
icon_path = "wi-hot.png"
|
||||
elif thisdayweather["maxwind_kph"] > 40:
|
||||
gauge.add('Vent', [{'value': thisdayweather["maxwind_kph"], 'color': '#999'}])
|
||||
elif thisdayweather["wind_gust"] > 40:
|
||||
gauge.add('Vent', [{'value': thisdayweather["wind_gust"], 'color': '#999'}])
|
||||
icon_path = "wi-strong-wind.png"
|
||||
elif thisdayweather["avgvis_km"] < 10:
|
||||
gauge.add('Visibilité', [{'value': thisdayweather["avgvis_km"] * 10, 'color': '#999'}])
|
||||
icon_path = "wi-fog.png"
|
||||
elif "air_quality" in thisdayweather:
|
||||
gauge.add("Qualité de l'air", [{'value': thisdayweather["air_quality"]["gb-defra-index"] * 10}])
|
||||
if thisdayweather["air_quality"]["gb-defra-index"] >= 5:
|
||||
@ -236,7 +229,7 @@ class WeatherRainModule:
|
||||
else:
|
||||
icon_path = "wi-smoke.png"
|
||||
else:
|
||||
gauge.add('Vent', [{'value': thisdayweather["maxwind_kph"], 'color': '#999'}])
|
||||
gauge.add('Vent', [{'value': thisdayweather["wind_speed"], 'color': '#999'}])
|
||||
icon_path = "wi-wind-beaufort-1.png"
|
||||
|
||||
image = Image.open(io.BytesIO(gauge.render_to_png()))
|
||||
@ -254,7 +247,7 @@ class WeatherTemperatureModule:
|
||||
|
||||
def draw_module(self, config, width, height):
|
||||
thisdayweather = list(itertools.islice(WeatherAPI().get_daily(), 2))
|
||||
if datetime.now().hour >= 19 and thisdayweather[1]["totalprecip_mm"] > thisdayweather[0]["totalprecip_mm"]:
|
||||
if datetime.now().hour >= 19 and thisdayweather[1]["pop"] > thisdayweather[0]["pop"]:
|
||||
thisdayweather = thisdayweather[1]
|
||||
else:
|
||||
thisdayweather = thisdayweather[0]
|
||||
@ -264,22 +257,22 @@ class WeatherTemperatureModule:
|
||||
hourly_min = 0
|
||||
hourly_max = 0
|
||||
for h in hours_weather:
|
||||
if hourly_min > h["temp_c"]:
|
||||
hourly_min = h["temp_c"]
|
||||
if hourly_max < h["temp_c"]:
|
||||
hourly_max = h["temp_c"]
|
||||
if hourly_min > h["temp"]:
|
||||
hourly_min = h["temp"]
|
||||
if hourly_max < h["temp"]:
|
||||
hourly_max = h["temp"]
|
||||
|
||||
line_chart = pygal.Line(config.pygal_config, interpolate='hermite', interpolation_parameters={'type': 'kochanek_bartels', 'b': -1, 'c': 1, 't': 1}, width=width+10, height=height, inverse_y_axis=False, x_label_rotation=45, range=(hourly_min, hourly_max), secondary_range=(0,100) if thisdayweather["totalprecip_mm"] + thisdayweather["totalsnow_cm"] > 0 else (0,10), **config.charts_opts)
|
||||
line_chart = pygal.Line(config.pygal_config, interpolate='hermite', interpolation_parameters={'type': 'kochanek_bartels', 'b': -1, 'c': 1, 't': 1}, width=width+10, height=height, inverse_y_axis=False, x_label_rotation=45, range=(hourly_min, hourly_max), secondary_range=(0,100) if thisdayweather["pop"] > 0 else (0,10), **config.charts_opts)
|
||||
line_chart.value_formatter = lambda x: "%d" % x
|
||||
|
||||
line_chart.x_labels = [WeatherAPI().read_timestamp(d["time_epoch"]).strftime("%Hh") if WeatherAPI().read_timestamp(d["time_epoch"]).hour % 2 == 0 else "" for d in hours_weather[:self.limit_futur]]
|
||||
line_chart.x_labels = [WeatherAPI().read_timestamp(d["dt"]).strftime("%Hh") if WeatherAPI().read_timestamp(d["dt"]).hour % 2 == 0 else "" for d in hours_weather[:self.limit_futur]]
|
||||
|
||||
line_chart.add('Températures', [d["temp_c"] for d in hours_weather[:self.limit_futur]], show_dots=False)
|
||||
line_chart.add('Températures', [d["temp"] for d in hours_weather[:self.limit_futur]], show_dots=False)
|
||||
|
||||
if thisdayweather["totalprecip_mm"] + thisdayweather["totalsnow_cm"] > 0:
|
||||
line_chart.add('Précipitations', [d["chance_of_rain"] + d["chance_of_snow"] for d in hours_weather[:self.limit_futur]], secondary=True, show_dots=False, fill=True if hourly_min == 0 else False)
|
||||
if thisdayweather["pop"] > 0:
|
||||
line_chart.add('Précipitations', [d["pop"]*100 for d in hours_weather[:self.limit_futur]], secondary=True, show_dots=False, fill=True if hourly_min == 0 else False)
|
||||
else:
|
||||
line_chart.add('Index UV', [d["uv"] for d in hours_weather[:self.limit_futur]], secondary=True, show_dots=False)
|
||||
line_chart.add('Index UV', [d["uvi"] for d in hours_weather[:self.limit_futur]], secondary=True, show_dots=False)
|
||||
|
||||
img = Image.open(io.BytesIO(line_chart.render_to_png()))
|
||||
draw = ImageDraw.Draw(img)
|
||||
@ -296,7 +289,7 @@ class WeeklyWeatherModule:
|
||||
|
||||
def __init__(self):
|
||||
self.first_day = 1
|
||||
self.limit_futur = 7
|
||||
self.limit_futur = 5
|
||||
|
||||
def draw_module(self, config, width, height):
|
||||
image = Image.new('RGB', (width, height), 'white')
|
||||
@ -317,24 +310,24 @@ class WeeklyWeatherModule:
|
||||
)
|
||||
|
||||
temp = []
|
||||
for day in weekweather[self.first_day:self.first_day+self.limit_futur]:
|
||||
temp.append(day["mintemp_c"])
|
||||
temp.append(day["maxtemp_c"])
|
||||
for day in weekweather[max(0,self.first_day-1):self.first_day+self.limit_futur]:
|
||||
temp.append(day["temp"]["min"])
|
||||
temp.append(day["temp"]["max"])
|
||||
t_min = min(temp)
|
||||
t_max = max(temp)
|
||||
t_scale = (width - day_size - 30) / (t_max - t_min)
|
||||
|
||||
i = 1
|
||||
for day in weekweather[self.first_day:self.first_day+self.limit_futur]:
|
||||
icon = Image.open(os.path.join(config.icons_dir, "weather", WeatherAPI.get_icon(day["condition"]["code"]))).resize((day_size, day_size))
|
||||
icon = Image.open(os.path.join(config.icons_dir, "weather", WeatherAPI.get_icon(day["weather"][0]["id"]))).resize((day_size, day_size))
|
||||
image.paste(icon, (0, i * day_size), icon)
|
||||
|
||||
draw.text(
|
||||
(15 + 2 + day_size + int((day["mintemp_c"]-t_min)*t_scale), i*day_size + 4),
|
||||
"%d˚" % math.trunc(day["mintemp_c"]),
|
||||
(15 + 2 + day_size + int((day["temp"]["min"]-t_min)*t_scale), i*day_size + 4),
|
||||
"%d˚" % math.trunc(day["temp"]["min"]),
|
||||
fill="black", anchor="rt", font=fnt_R
|
||||
)
|
||||
summary_size = fnt_R.getlength(day["date"].strftime("%a") + " : " + day["condition"]["text"])
|
||||
summary_size = fnt_R.getlength(day["date"].strftime("%a") + " : " + day["weather"][0]["description"])
|
||||
draw.text(
|
||||
(day_size + (width - day_size - summary_size) / 2, (i + 1) * day_size - 6),
|
||||
day["date"].strftime("%a") + " : ",
|
||||
@ -342,22 +335,22 @@ class WeeklyWeatherModule:
|
||||
)
|
||||
draw.text(
|
||||
(day_size + (width - day_size + summary_size) / 2, (i + 1) * day_size - 6),
|
||||
day["condition"]["text"],
|
||||
day["weather"][0]["description"],
|
||||
fill="black", anchor="rs", font=fnt_R
|
||||
)
|
||||
draw.text(
|
||||
(day_size + int((day["maxtemp_c"]-t_min)*t_scale) + 2, i * day_size + 4),
|
||||
"%d˚" % math.trunc(day["maxtemp_c"]),
|
||||
(day_size + int((day["temp"]["max"]-t_min)*t_scale) + 2, i * day_size + 4),
|
||||
"%d˚" % math.trunc(day["temp"]["max"]),
|
||||
fill="black", anchor="lt", font=fnt_R
|
||||
)
|
||||
|
||||
try:
|
||||
draw.rounded_rectangle(
|
||||
(15 + day_size + int((day["mintemp_c"]-t_min)*t_scale),i*day_size + 4,day_size + int((day["maxtemp_c"]-t_min)*t_scale),i*day_size + 14),
|
||||
(15 + day_size + int((day["temp"]["min"]-t_min)*t_scale),i*day_size + 4,day_size + int((day["temp"]["max"]-t_min)*t_scale),i*day_size + 14),
|
||||
radius=5, fill="black")
|
||||
except AttributeError:
|
||||
draw.rectangle(
|
||||
(15 + day_size + int((day["mintemp_c"]-t_min)*t_scale),i*day_size + 4,day_size + int((day["maxtemp_c"]-t_min)*t_scale),i*day_size + 14),
|
||||
(15 + day_size + int((day["temp"]["min"]-t_min)*t_scale),i*day_size + 4,day_size + int((day["temp"]["max"]-t_min)*t_scale),i*day_size + 14),
|
||||
fill="black")
|
||||
i += 1
|
||||
|
||||
|
@ -5,211 +5,285 @@ import os
|
||||
import urllib.error
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
class WeatherAPI:
|
||||
class DarkSkyAPI:
|
||||
|
||||
def __init__(self, apikey=None, gps=None, opts={"lang": "fr", "units": "metric"}):
|
||||
self.apikey = apikey or os.environ["WEATHERAPIKEY"]
|
||||
self.baseurl = "http://api.weatherapi.com/v1"
|
||||
self.baseurl = "https://api.openweathermap.org/data/3.0/onecall"
|
||||
self.default_gps = gps or ("GPS" in os.environ and os.environ["GPS"]) or "48.8127,2.3437"
|
||||
self.opts = opts
|
||||
|
||||
self._cached_file = ".weather-%s-%s.cache"
|
||||
self._cached_file = ".darksky-%s.cache"
|
||||
|
||||
|
||||
def get_weather(self, apitype="forecast", gps=None, **params):
|
||||
def get_weather(self, gps=None):
|
||||
if gps is None:
|
||||
gps = self.default_gps
|
||||
|
||||
cached_filename = self._cached_file % (apitype + ("" if "dt" not in params else "-{}".format(params["dt"])), gps)
|
||||
# Read the mod time
|
||||
statinfo = None
|
||||
try:
|
||||
statinfo = os.stat(cached_filename)
|
||||
statinfo = os.stat(self._cached_file % gps)
|
||||
except:
|
||||
pass
|
||||
|
||||
params["q"] = gps
|
||||
params["key"] = str(self.apikey)
|
||||
params["alerts"] = "yes"
|
||||
params["aqi"] = "yes"
|
||||
for k in self.opts:
|
||||
params[k] = self.opts[k]
|
||||
|
||||
if statinfo is None or datetime.fromtimestamp(statinfo.st_mtime, tz=timezone.utc) + timedelta(hours=1) < datetime.now(tz=timezone.utc):
|
||||
# Do the request and save it
|
||||
try:
|
||||
with urllib.request.urlopen(self.baseurl + "/" + apitype + ".json?" + urllib.parse.urlencode(params)) as f:
|
||||
with open(cached_filename, 'wb') as fd:
|
||||
(lat,lon) = gps.split(",")
|
||||
with urllib.request.urlopen(self.baseurl + "?appid=" + str(self.apikey) + "&lat=" + str(lat) + "&lon=" + str(lon) + "&" + ("&".join([opt+"="+self.opts[opt] for opt in self.opts]))) as f:
|
||||
with open(self._cached_file % gps, 'wb') as fd:
|
||||
fd.write(f.read())
|
||||
except ConnectionResetError:
|
||||
pass
|
||||
except urllib.error.URLError:
|
||||
pass
|
||||
#except urllib.error.URLError:
|
||||
# pass
|
||||
|
||||
|
||||
# Retrieve cached data
|
||||
res = {}
|
||||
with open(cached_filename) as f:
|
||||
with open(self._cached_file % gps) as f:
|
||||
res = json.load(f)
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def get_icon(icon, night=False, current=False):
|
||||
if icon == 1000:
|
||||
# 200: Thunderstorm
|
||||
if icon < 300:
|
||||
if icon == 200 or icon == 201 or icon == 202:
|
||||
if not night:
|
||||
return "wi-day-thunderstorm.png"
|
||||
else:
|
||||
return "wi-night-thunderstorm.png"
|
||||
elif icon == 210 or icon == 211:
|
||||
return "wi-thunderstorm.png"
|
||||
elif icon == 212 or icon == 221:
|
||||
return "wi-lightning.png"
|
||||
elif icon == 230 or icon == 231 or icon == 232:
|
||||
if not night:
|
||||
return "wi-day-storm-showers.png"
|
||||
else:
|
||||
return "wi-night-storm-showers.png"
|
||||
else:
|
||||
return "wi-thunderstorm.png"
|
||||
|
||||
# 300: Drizzle
|
||||
elif icon < 400:
|
||||
if icon < 311:
|
||||
if not night:
|
||||
return "wi-day-showers.png"
|
||||
else:
|
||||
return "wi-night-showers.png"
|
||||
else:
|
||||
return "wi-showers.png"
|
||||
|
||||
# 500: Rain
|
||||
elif icon < 600:
|
||||
if icon == 500:
|
||||
if not night:
|
||||
return "wi-day-rain.png"
|
||||
else:
|
||||
return "wi-night-rain.png"
|
||||
if icon < 510:
|
||||
return "wi-rain.png"
|
||||
elif icon < 520:
|
||||
if current:
|
||||
return "wi-hail.png"
|
||||
elif not night:
|
||||
return "wi-day-hail.png"
|
||||
else:
|
||||
return "wi-night-hail.png"
|
||||
elif icon == 520:
|
||||
if not night:
|
||||
return "wi-day-showers.png"
|
||||
else:
|
||||
return "wi-night-showers.png"
|
||||
elif icon > 520:
|
||||
return "wi-showers.png"
|
||||
else:
|
||||
return "wi-rain.png"
|
||||
|
||||
# 600: Snow
|
||||
elif icon < 700:
|
||||
if icon == 600:
|
||||
if not night:
|
||||
return "wi-day-snow.png"
|
||||
else:
|
||||
return "wi-night-alt-snow.png"
|
||||
elif icon < 610:
|
||||
return "wi-snow.png"
|
||||
elif icon < 620:
|
||||
if current:
|
||||
return "wi-sleet.png"
|
||||
if not night:
|
||||
return "wi-day-sleet.png"
|
||||
else:
|
||||
return "wi-night-alt-sleet.png"
|
||||
elif icon == 620:
|
||||
if not night:
|
||||
return "wi-day-snow-wind.png"
|
||||
else:
|
||||
return "wi-night-snow-wind.png"
|
||||
elif icon < 630:
|
||||
return "wi-snow-wind.png"
|
||||
else:
|
||||
return "wi-snow.png"
|
||||
|
||||
# Atmosphere
|
||||
elif icon < 800:
|
||||
if icon == 701:
|
||||
if not night:
|
||||
return "wi-day-haze.png"
|
||||
else:
|
||||
return "wi-night-fog.png"
|
||||
elif icon < 720:
|
||||
return "wi-smoke.png"
|
||||
elif icon < 730:
|
||||
if not night:
|
||||
return "wi-day-haze.png"
|
||||
else:
|
||||
return "wi-night-fog.png"
|
||||
elif icon < 740:
|
||||
return "wi-dust.png"
|
||||
elif icon < 750:
|
||||
if not night:
|
||||
return "wi-day-fog.png"
|
||||
else:
|
||||
return "wi-night-fog.png"
|
||||
elif icon == 751:
|
||||
return "wi-sandstorm.png"
|
||||
elif icon < 762:
|
||||
return "wi-dust.png"
|
||||
elif icon == 762:
|
||||
return "wi-volcano.png"
|
||||
elif icon == 771:
|
||||
return "wi-strong-wind.png"
|
||||
elif icon == 781:
|
||||
return "wi-tornado.png"
|
||||
|
||||
# 800: Clear
|
||||
if icon == 800:
|
||||
if not night:
|
||||
return "wi-day-sunny.png"
|
||||
else:
|
||||
return "wi-night-clear.png"
|
||||
elif icon == 1003:
|
||||
if not night:
|
||||
return "wi-day-cloudy.png"
|
||||
else:
|
||||
return "wi-night-alt-cloudy.png"
|
||||
elif icon == 1006:
|
||||
return "wi-cloudy.png"
|
||||
elif icon == 1009:
|
||||
|
||||
# 800: Clouds
|
||||
elif icon == 801:
|
||||
if not night:
|
||||
return "wi-day-sunny-overcast.png"
|
||||
else:
|
||||
return "wi-night-alt-partly-cloudy.png"
|
||||
elif icon == 1030 or icon == 1072:
|
||||
elif icon == 802:
|
||||
if not night:
|
||||
return "wi-day-haze.png"
|
||||
return "wi-day-cloudy.png"
|
||||
else:
|
||||
return "wi-night-fog.png"
|
||||
elif icon == 1063:
|
||||
if not night:
|
||||
return "wi-day-rain.png"
|
||||
else:
|
||||
return "wi-night-alt-rain.png"
|
||||
elif icon == 1066:
|
||||
if not night:
|
||||
return "wi-day-snow.png"
|
||||
else:
|
||||
return "wi-night-alt-snow.png"
|
||||
elif icon == 1069 or icon == 1204:
|
||||
if not night:
|
||||
return "wi-day-sleet.png"
|
||||
else:
|
||||
return "wi-night-alt-sleet.png"
|
||||
elif icon == 1087:
|
||||
if not night:
|
||||
return "wi-day-lightning.png"
|
||||
else:
|
||||
return "wi-night-alt-lightning.png"
|
||||
elif icon == 1114 or icon == 1219 or icon == 1222 or icon == 1258:
|
||||
return "wi-snow.png"
|
||||
elif icon == 1117 or icon == 1225:
|
||||
return "wi-snow-wind.png"
|
||||
elif icon == 1135 or icon == 1147:
|
||||
return "wi-fog.png"
|
||||
elif icon == 1150 or icon == 1153:
|
||||
return "wi-sprinkle.png"
|
||||
elif icon == 1168 or icon == 1171 or icon == 1198 or icon == 1201:
|
||||
return "wi-snowflake-cold.png"
|
||||
elif icon == 1180 or icon == 1183 or icon == 1186:
|
||||
if not night:
|
||||
return "wi-day-rain.png"
|
||||
else:
|
||||
return "wi-night-alt-rain.png"
|
||||
elif icon == 1189 or icon == 1192 or icon == 1195:
|
||||
return "wi-rain.png"
|
||||
elif icon == 1240 or icon == 1243:
|
||||
return "wi-showers.png"
|
||||
elif icon == 1246:
|
||||
return "wi-tsunami.png"
|
||||
elif icon == 1207 or icon == 1249 or icon == 1252:
|
||||
return "wi-sleet.png"
|
||||
elif icon == 1210 or icon == 1213 or icon == 1216 or icon == 1255:
|
||||
if not night:
|
||||
return "wi-day-snow.png"
|
||||
else:
|
||||
return "wi-night-snow.png"
|
||||
elif icon == 1237:
|
||||
return "wi-hail.png"
|
||||
elif icon == 1261 or icon == 1264:
|
||||
if not night:
|
||||
return "wi-day-hail.png"
|
||||
else:
|
||||
return "wi-night-hail.png"
|
||||
elif icon == 1273 or icon == 1276:
|
||||
if not night:
|
||||
return "wi-day-thunderstorm.png"
|
||||
else:
|
||||
return "wi-night-thunderstorm.png"
|
||||
elif icon == 1279 or icon == 1282:
|
||||
if not night:
|
||||
return "wi-day-snow-thunderstorm.png"
|
||||
else:
|
||||
return "wi-night-snow-thunderstorm.png"
|
||||
else:
|
||||
return "wi-alien.png"
|
||||
return "wi-night-alt-cloudy.png"
|
||||
elif icon == 804:
|
||||
return "wi-cloudy.png"
|
||||
elif icon < 900:
|
||||
return "wi-cloud.png"
|
||||
|
||||
return "wi-alien.png"
|
||||
|
||||
|
||||
def get_moon_icon(self, day=0):
|
||||
moon_phase = list(itertools.islice(self.get_daily(), 1))[day]["moon_phase"]
|
||||
thisdayweather = list(itertools.islice(self.get_daily(), 1))[0]
|
||||
moon_phase = thisdayweather["moon_phase"]
|
||||
|
||||
if moon_phase == "New Moon":
|
||||
if moon_phase < 0.035:
|
||||
return "wi-moon-alt-new.png"
|
||||
elif moon_phase == "Waxing Crescent":
|
||||
elif moon_phase < 0.071:
|
||||
return "wi-moon-alt-waxing-crescent-1.png"
|
||||
elif moon_phase < 0.107:
|
||||
return "wi-moon-alt-waxing-crescent-2.png"
|
||||
elif moon_phase < 0.142:
|
||||
return "wi-moon-alt-waxing-crescent-3.png"
|
||||
elif moon_phase < 0.178:
|
||||
return "wi-moon-alt-waxing-crescent-4.png"
|
||||
elif moon_phase == "First Quarter":
|
||||
elif moon_phase < 0.214:
|
||||
return "wi-moon-alt-waxing-crescent-5.png"
|
||||
elif moon_phase < 0.25:
|
||||
return "wi-moon-alt-waxing-crescent-6.png"
|
||||
elif moon_phase < 0.285:
|
||||
return "wi-moon-alt-first-quarter.png"
|
||||
elif moon_phase == "Waxing Gibbous":
|
||||
elif moon_phase < 0.321:
|
||||
return "wi-moon-alt-waxing-gibbous-1.png"
|
||||
elif moon_phase < 0.357:
|
||||
return "wi-moon-alt-waxing-gibbous-2.png"
|
||||
elif moon_phase < 0.392:
|
||||
return "wi-moon-alt-waxing-gibbous-3.png"
|
||||
elif moon_phase < 0.428:
|
||||
return "wi-moon-alt-waxing-gibbous-4.png"
|
||||
elif moon_phase == "Full Moon":
|
||||
elif moon_phase < 0.464:
|
||||
return "wi-moon-alt-waxing-gibbous-5.png"
|
||||
elif moon_phase < 0.5:
|
||||
return "wi-moon-alt-waxing-gibbous-6.png"
|
||||
elif moon_phase < 0.535:
|
||||
return "wi-moon-alt-full.png"
|
||||
elif moon_phase == "Waning Gibbous":
|
||||
elif moon_phase < 0.571:
|
||||
return "wi-moon-alt-waning-gibbous-1.png"
|
||||
elif moon_phase < 0.607:
|
||||
return "wi-moon-alt-waning-gibbous-2.png"
|
||||
elif moon_phase < 0.642:
|
||||
return "wi-moon-alt-waning-gibbous-3.png"
|
||||
elif moon_phase < 0.678:
|
||||
return "wi-moon-alt-waning-gibbous-4.png"
|
||||
elif moon_phase == "Last Quarter":
|
||||
elif moon_phase < 0.714:
|
||||
return "wi-moon-alt-waning-gibbous-5.png"
|
||||
elif moon_phase < 0.75:
|
||||
return "wi-moon-alt-waning-gibbous-6.png"
|
||||
elif moon_phase < 0.785:
|
||||
return "wi-moon-alt-third-quarter.png"
|
||||
else:
|
||||
elif moon_phase < 0.821:
|
||||
return "wi-moon-alt-waning-crescent-1.png"
|
||||
elif moon_phase < 0.857:
|
||||
return "wi-moon-alt-waning-crescent-2.png"
|
||||
elif moon_phase < 0.892:
|
||||
return "wi-moon-alt-waning-crescent-3.png"
|
||||
elif moon_phase < 0.928:
|
||||
return "wi-moon-alt-waning-crescent-4.png"
|
||||
elif moon_phase < 0.964:
|
||||
return "wi-moon-alt-waning-crescent-5.png"
|
||||
else:
|
||||
return "wi-moon-alt-waning-crescent-6.png"
|
||||
|
||||
|
||||
def get_currently(self, *args, **kwargs):
|
||||
return self.get_weather("current", *args, **kwargs)["current"]
|
||||
cur = self.get_weather(*args, **kwargs)["current"]
|
||||
cur["is_day"] = True
|
||||
return cur
|
||||
|
||||
|
||||
def get_forecast(self, *args, **kwargs):
|
||||
for i in [0, 1, 2, 3]:
|
||||
enddt = datetime.now() + timedelta(days=i)
|
||||
v = self.get_weather(*args, **kwargs, dt=enddt.strftime("%Y-%m-%d"), alerts="yes")["forecast"]["forecastday"][0]
|
||||
v["day"]["date"] = enddt
|
||||
yield v
|
||||
|
||||
def get_hourly(self, *args, **kwargs):
|
||||
now = datetime.now().astimezone(ZoneInfo("Europe/Paris"))
|
||||
for d in self.get_forecast(*args, **kwargs):
|
||||
for h in d["hour"]:
|
||||
if d["day"]["date"].day == now.day and now > self.read_timestamp(h["time_epoch"]) + timedelta(hours=1):
|
||||
continue
|
||||
yield h
|
||||
return self.get_weather(*args, **kwargs)["hourly"]
|
||||
|
||||
|
||||
def get_daily(self, *args, **kwargs):
|
||||
for d in self.get_forecast(*args, **kwargs):
|
||||
yield {
|
||||
**d["day"],
|
||||
**d["astro"]
|
||||
}
|
||||
for d in self.get_weather(*args, **kwargs)["daily"]:
|
||||
d["date"] = datetime.fromtimestamp(d["dt"])
|
||||
yield d
|
||||
|
||||
def has_alerts(self, *args, **kwargs):
|
||||
return "alerts" in self.get_weather(*args, **kwargs) and len(self.get_weather(*args, **kwargs)["alerts"]) > 0
|
||||
|
||||
def get_alerts(self, *args, **kwargs):
|
||||
for i in [0, 1, 2, 3]:
|
||||
enddt = datetime.now() + timedelta(days=i)
|
||||
for a in self.get_weather(*args, **kwargs, dt=enddt.strftime("%Y-%m-%d"))["alerts"]["alert"]:
|
||||
yield a
|
||||
w = self.get_weather(*args, **kwargs)
|
||||
if "alerts" in w:
|
||||
return w["alerts"]
|
||||
return []
|
||||
|
||||
def read_timestamp(self, timestamp, *args, **kwargs):
|
||||
PARIS = ZoneInfo("Europe/Paris")
|
||||
return datetime.fromtimestamp(int(timestamp), tz=timezone.utc).astimezone(PARIS)
|
||||
wth = self.get_weather(*args, **kwargs)
|
||||
|
||||
tz = timezone(timedelta(seconds=wth["timezone_offset"]), wth["timezone"])
|
||||
return datetime.fromtimestamp(timestamp, tz=tz)
|
||||
|
||||
|
||||
#WeatherAPI = TomorrowAPI
|
||||
WeatherAPI = DarkSkyAPI
|
||||
|
||||
if __name__ == '__main__':
|
||||
dsa = WeatherAPI()
|
||||
print(json.dumps(dsa.get_currently()))
|
||||
#print(json.dumps([d for d in dsa.get_daily()][0]))
|
||||
dsa = DarkSkyAPI()
|
||||
print(dsa.get_currently())
|
||||
|
Loading…
Reference in New Issue
Block a user