Switch to tomorrow weather API

This commit is contained in:
nemunaire 2023-04-09 15:33:43 +02:00
parent 54a757e20d
commit ae73f68444
2 changed files with 350 additions and 114 deletions

View File

@ -56,9 +56,9 @@ class WeatherToolbarModule:
infos = {
"Vent": "%d km/h" % weather["windSpeed"],
"Humidité": "%d%%" % (weather["humidity"] * 100),
"Humidité": "%d%%" % (weather["humidity"]),
"Indice UV": str(weather["uvIndex"]),
"Pression": "%d hPa" % weather["pressure"],
"Pression": "%d hPa" % weather["pressureSurfaceLevel"],
}
txt = draw_format_infos(infos, width, height, fnt_R, fnt_B, self.label_margin, align_height=height/2, anchor="lm")
@ -82,21 +82,21 @@ class WeatherJumboCurrentModule:
# current
curweather = WeatherAPI().get_currently()
icon = Image.open("icons/" + WeatherAPI.get_icon(curweather["icon"], current=True)).resize((height, height))
icon = Image.open("icons/" + WeatherAPI.get_icon(curweather["weatherCode"], 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["temperature"]), curweather["summary"]),
"%d˚ %s." % (math.trunc(curweather["temperature"]), curweather["summary"] if "summary" in curweather else WeatherAPI.get_description(curweather["weatherCode"])),
fill="black", anchor="ld", font=fnt_Big
)
thisdayweather = WeatherAPI().get_daily()["data"][0]
thisdayweather = WeatherAPI().get_daily()[0]["values"]
infos = {
"Ressentie": "%d˚" % curweather["apparentTemperature"],
"Minimale": "%d˚" % thisdayweather["temperatureLow"],
"Maximale": "%d˚" % thisdayweather["temperatureHigh"],
"Ressentie": "%d˚" % curweather["temperatureApparent"],
"Minimale": "%d˚" % thisdayweather["temperatureMin"],
"Maximale": "%d˚" % thisdayweather["temperatureMax"],
}
txt = draw_format_infos(infos, (1-self.middle_align) * width, 20, fnt_R, fnt_B, 5, margin_bf_first=False, fill="black", anchor="lt")
@ -105,12 +105,13 @@ class WeatherJumboCurrentModule:
# day
fnt_Rig = ImageFont.truetype(config.fnt_R_path, 20)
dailyweather = WeatherAPI().get_daily()
dayweather = WeatherAPI().get_hourly()
if dayweather["data"][0]["summary"] != dayweather["data"][1]["summary"]:
display_longtext(draw, (width*self.middle_align, height/1.28), dayweather["data"][1]["summary"] + " la prochaine heure.\n" + dayweather["summary"], fill="black", anchor="lm", font=fnt_Rig, maxwidth=(1-self.middle_align)*width)
if dayweather[0]["values"]["weatherCode"] != dayweather[1]["values"]["weatherCode"]:
display_longtext(draw, (width*self.middle_align, height/1.28), WeatherAPI.get_description(dayweather[1]["values"]["weatherCode"]) + " la prochaine heure.\n" + WeatherAPI.get_description(dailyweather[0]["values"]["weatherCodeMax"]) + " aujourd'hui.", fill="black", anchor="lm", font=fnt_Rig, maxwidth=(1-self.middle_align)*width)
else:
display_longtext(draw, (width*self.middle_align, height/1.28), dayweather["summary"], fill="black", anchor="lm", font=fnt_Rig, maxwidth=(1-self.middle_align)*width)
display_longtext(draw, (width*self.middle_align, height/1.28), WeatherAPI.get_description(dayweather[0]["values"]["weatherCodeMax"]) + " aujourd'hui", fill="black", anchor="lm", font=fnt_Rig, maxwidth=(1-self.middle_align)*width)
return image
@ -132,7 +133,7 @@ class WeatherSunModule:
draw = ImageDraw.Draw(image)
fnt_R = ImageFont.truetype(config.fnt_R_path, int(height*0.7))
thisdayweather = WeatherAPI().get_daily()["data"][0]
thisdayweather = WeatherAPI().get_daily()[0]["values"]
import time
infos = {
@ -162,32 +163,31 @@ class WeatherRainModule:
def draw_module(self, config, width, height):
if datetime.now().hour >= 21:
thisdayweather = WeatherAPI().get_daily()["data"][1]
thisdayweather = WeatherAPI().get_daily()[1]["values"]
else:
thisdayweather = WeatherAPI().get_daily()["data"][0]
thisdayweather = WeatherAPI().get_daily()[0]["values"]
gauge = pygal.SolidGauge(config.pygal_config, half_pie=True, inner_radius=0.70, width=width, height=height*1.55, style=config.pygal_custom_style, show_legend=False, margin_top=-height*0.58, margin_left=1, margin_right=1)
percent_formatter = lambda x: '{:.10g}%'.format(x)
gauge.value_formatter = percent_formatter
if thisdayweather["precipProbability"] == 0 and thisdayweather["uvIndex"] > 4:
gauge.add('Index UV', [{'value': thisdayweather["uvIndex"] * 10}])
if thisdayweather["precipitationProbabilityMax"] == 0 and thisdayweather["uvIndexMax"] > 4:
gauge.add('Index UV', [{'value': thisdayweather["uvIndexMax"] * 10}])
icon_path = "wi-hot.png"
elif thisdayweather["precipProbability"] > 0:
gauge.add('Pluie', [{'value': thisdayweather["precipProbability"] * 100 + 1}])
elif thisdayweather["precipitationProbabilityMax"] > 0:
gauge.add('Pluie', [{'value': thisdayweather["precipitationProbabilityMax"] + 1}])
icon_path = "wi-umbrella.png"
elif thisdayweather["windSpeed"] > 50:
gauge.add('Vent', [{'value': thisdayweather["windSpeed"], 'color': '#999'}])
elif thisdayweather["windSpeedMax"] > 50:
gauge.add('Vent', [{'value': thisdayweather["windSpeedMax"], 'color': '#999'}])
icon_path = "wi-strong-wind.png"
elif thisdayweather["visibility"] < 10:
gauge.add('Visibilité', [{'value': thisdayweather["visibility"] * 10, 'color': '#999'}])
elif thisdayweather["visibilityMin"] < 10:
gauge.add('Visibilité', [{'value': thisdayweather["visibilityMin"] * 10, 'color': '#999'}])
icon_path = "wi-fog.png"
elif thisdayweather["cloudCover"] > 0.4:
gauge.add('Couverture nuageuse', [{'value': thisdayweather["cloudCover"] * 100, 'color': '#999'}])
elif thisdayweather["cloudCoverAvg"] > 40:
gauge.add('Couverture nuageuse', [{'value': thisdayweather["cloudCoverAvg"], 'color': '#999'}])
icon_path = "wi-cloudy.png"
else:
gauge.add('Pluie', [{'value': thisdayweather["precipProbability"] * 100}])
gauge.add('Pluie', [{'value': thisdayweather["precipitationProbabilityMax"]}])
icon_path = "wi-na.png"
image = Image.open(io.BytesIO(gauge.render_to_png()))
@ -204,8 +204,8 @@ class WeatherTemperatureModule:
self.limit_futur = 30
def draw_module(self, config, width, height):
thisdayweather = WeatherAPI().get_daily()["data"]
if datetime.now().hour >= 19 and thisdayweather[1]["precipProbability"] > thisdayweather[0]["precipProbability"]:
thisdayweather = WeatherAPI().get_daily()
if datetime.now().hour >= 19 and thisdayweather[1]["precipitationProbabilityMax"] > thisdayweather[0]["precipitationProbabilityMax"]:
thisdayweather = thisdayweather[1]
else:
thisdayweather = thisdayweather[0]
@ -214,25 +214,34 @@ class WeatherTemperatureModule:
hourly_min = 0
hourly_max = 0
for h in hours_weather["data"]:
if hourly_min > h["temperature"]:
hourly_min = h["temperature"]
if hourly_max < h["temperature"]:
hourly_max = h["temperature"]
for h in hours_weather:
if hourly_min > h["values"]["temperature"]:
hourly_min = h["values"]["temperature"]
if hourly_max < h["values"]["temperature"]:
hourly_max = h["values"]["temperature"]
line_chart = pygal.Line(config.pygal_config, interpolate='cubic', width=width+10, height=height, inverse_y_axis=False, x_label_rotation=45, range=(hourly_min, hourly_max), secondary_range=(0,100) if thisdayweather["precipProbability"] > 0 else (0,10), **config.charts_opts)
line_chart = pygal.Line(config.pygal_config, interpolate='cubic', width=width+10, height=height, inverse_y_axis=False, x_label_rotation=45, range=(hourly_min, hourly_max), secondary_range=(0,100) if thisdayweather["values"]["precipitationProbabilityMax"] > 0 else (0,10), **config.charts_opts)
line_chart.value_formatter = lambda x: "%d" % x
line_chart.x_labels = [WeatherAPI().read_timestamp(d["time"]).strftime("%Hh") if datetime.fromtimestamp(d["time"]).hour % 2 == 0 else "" for d in hours_weather["data"][:self.limit_futur]]
line_chart.x_labels = [WeatherAPI().read_timestamp(d["time"]).strftime("%Hh") if WeatherAPI().read_timestamp(d["time"]).hour % 2 == 0 else "" for d in hours_weather[:self.limit_futur]]
line_chart.add('Températures', [d["temperature"] for d in hours_weather["data"][:self.limit_futur]], show_dots=False)
line_chart.add('Températures', [d["values"]["temperature"] for d in hours_weather[:self.limit_futur]], show_dots=False)
if thisdayweather["precipProbability"] > 0:
line_chart.add('Précipitations', [d["precipProbability"] * 100 for d in hours_weather["data"][:self.limit_futur]], secondary=True, show_dots=False, fill=True if hourly_min == 0 else False)
if thisdayweather["values"]["precipitationProbabilityMax"] > 0:
line_chart.add('Précipitations', [d["values"]["precipitationProbability"] 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["uvIndex"] for d in hours_weather["data"][:self.limit_futur]], secondary=True, show_dots=False)
line_chart.add('Index UV', [d["values"]["uvIndex"] for d in hours_weather[:self.limit_futur]], secondary=True, show_dots=False)
return Image.open(io.BytesIO(line_chart.render_to_png()))
img = Image.open(io.BytesIO(line_chart.render_to_png()))
draw = ImageDraw.Draw(img)
# Add EcoWatt signal
#for ecowatt
#draw.rectangle(
# (15 + day_size + int((day["temperatureLow"]-t_min)*t_scale),i*day_size + 4,day_size + int((day["temperatureHigh"]-t_min)*t_scale),i*day_size + 14),
# fill="black")
return img
class WeeklyWeatherModule:
@ -247,37 +256,36 @@ class WeeklyWeatherModule:
fnt_B = ImageFont.truetype(config.fnt_RB_path, 14)
weekweather = WeatherAPI().get_daily()
daysweather = weekweather["data"]
nbdays = len(daysweather[self.first_day:self.first_day+self.limit_futur])
day_size = int(height / (nbdays + 1))
nbdays = len(weekweather[self.first_day:self.first_day+self.limit_futur])
day_size = min(40, int(height / (nbdays + 1)))
display_longtext(draw,
(day_size + (width - day_size)/2, day_size / 2 + 5),
weekweather["summary"],
weekweather["summary"] if "summary" in weekweather else "",
fill="black", anchor="mm", font=fnt_B,
maxwidth=width - day_size
)
temp = []
for day in daysweather[self.first_day:self.first_day+self.limit_futur]:
temp.append(day["temperatureLow"])
temp.append(day["temperatureHigh"])
for day in weekweather[self.first_day:self.first_day+self.limit_futur]:
temp.append(day["values"]["temperatureMin"])
temp.append(day["values"]["temperatureMax"])
t_min = min(temp)
t_max = max(temp)
t_scale = (width - day_size - 30) / (t_max - t_min)
i = 1
for day in daysweather[self.first_day:self.first_day+self.limit_futur]:
icon = Image.open("icons/" + WeatherAPI.get_icon(day["icon"])).resize((day_size, day_size))
for day in weekweather[self.first_day:self.first_day+self.limit_futur]:
icon = Image.open("icons/" + WeatherAPI.get_icon(day["values"]["weatherCodeMax"])).resize((day_size, day_size))
image.paste(icon, (0, i * day_size), icon)
draw.text(
(15 + 2 + day_size + int((day["temperatureLow"]-t_min)*t_scale), i*day_size + 4),
"%d˚" % math.trunc(day["temperatureLow"]),
(15 + 2 + day_size + int((day["values"]["temperatureMin"]-t_min)*t_scale), i*day_size + 4),
"%d˚" % math.trunc(day["values"]["temperatureMax"]),
fill="black", anchor="rt", font=fnt_R
)
summary_size = fnt_R.getsize(WeatherAPI().read_timestamp(day["time"]).strftime("%a") + " : " + day["summary"])[0]
summary_size = fnt_R.getsize(WeatherAPI().read_timestamp(day["time"]).strftime("%a") + " : " + (day["values"]["summary"] if "summary" in day["values"] else WeatherAPI.get_description(day["values"]["weatherCodeMax"])))[0]
draw.text(
(day_size + (width - day_size - summary_size) / 2, (i + 1) * day_size - 6),
WeatherAPI().read_timestamp(day["time"]).strftime("%a") + " : ",
@ -285,22 +293,22 @@ class WeeklyWeatherModule:
)
draw.text(
(day_size + (width - day_size + summary_size) / 2, (i + 1) * day_size - 6),
day["summary"],
day["values"]["summary"] if "summary" in day["values"] else WeatherAPI.get_description(day["values"]["weatherCodeMax"]),
fill="black", anchor="rs", font=fnt_R
)
draw.text(
(day_size + int((day["temperatureHigh"]-t_min)*t_scale) + 2, i * day_size + 4),
"%d˚" % math.trunc(day["temperatureHigh"]),
(day_size + int((day["values"]["temperatureMax"]-t_min)*t_scale) + 2, i * day_size + 4),
"%d˚" % math.trunc(day["values"]["temperatureMax"]),
fill="black", anchor="lt", font=fnt_R
)
try:
draw.rounded_rectangle(
(15 + day_size + int((day["temperatureLow"]-t_min)*t_scale),i*day_size + 4,day_size + int((day["temperatureHigh"]-t_min)*t_scale),i*day_size + 14),
(15 + day_size + int((day["values"]["temperatureMin"]-t_min)*t_scale),i*day_size + 4,day_size + int((day["values"]["temperatureMax"]-t_min)*t_scale),i*day_size + 14),
radius=5, fill="black")
except AttributeError:
draw.rectangle(
(15 + day_size + int((day["temperatureLow"]-t_min)*t_scale),i*day_size + 4,day_size + int((day["temperatureHigh"]-t_min)*t_scale),i*day_size + 14),
(15 + day_size + int((day["values"]["temperatureMin"]-t_min)*t_scale),i*day_size + 4,day_size + int((day["values"]["temperatureMax"]-t_min)*t_scale),i*day_size + 14),
fill="black")
i += 1

View File

@ -4,34 +4,35 @@ import os
import urllib.error
import urllib.parse
import urllib.request
from zoneinfo import ZoneInfo
class DarkSkyAPI:
class TomorrowAPI:
def __init__(self, apikey=None, gps=None, opts={"lang": "fr", "units": "ca"}):
self.apikey = apikey or os.environ["DARKSKYAPIKEY"]
self.baseurl = "https://api.darksky.net/forecast"
def __init__(self, apikey=None, gps=None, opts={"units": "metric"}):
self.apikey = apikey or os.environ["TOMORROWAPIKEY"]
self.baseurl = "https://api.tomorrow.io/v4"
self.default_gps = gps or ("GPS" in os.environ and os.environ["GPS"]) or "48.8127,2.3437"
self.opts = opts
self._cached_file = ".darksky-%s.cache"
self._cached_file = ".weather-%s-%s.cache"
def get_weather(self, gps=None):
def get_weather(self, apitype="forecast", gps=None):
if gps is None:
gps = self.default_gps
# Read the mod time
statinfo = None
try:
statinfo = os.stat(self._cached_file % gps)
statinfo = os.stat(self._cached_file % (apitype, gps))
except:
pass
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 + "/" + str(self.apikey) + "/" + gps + "?" + "&".join([opt+"="+self.opts[opt] for opt in self.opts])) as f:
with open(self._cached_file % gps, 'wb') as fd:
with urllib.request.urlopen(self.baseurl + "/weather/" + apitype + "?location=" + gps + "&apikey=" + str(self.apikey) + "&" + ("&".join([opt+"="+self.opts[opt] for opt in self.opts]))) as f:
with open(self._cached_file % (apitype, gps), 'wb') as fd:
fd.write(f.read())
except ConnectionResetError:
pass
@ -41,64 +42,292 @@ class DarkSkyAPI:
# Retrieve cached data
res = {}
with open(self._cached_file % gps) as f:
with open(self._cached_file % (apitype, gps)) as f:
res = json.load(f)
return res
def get_icon(icon, current=False):
if icon == "clear-day":
return "wi-day-sunny.png"
elif icon == "clear-night":
return "wi-night-clear.png"
elif icon == "rain":
if not current:
return "wi-day-rain.png"
def get_icon(icon, night=False, current=False):
if icon == 1000:
if not night:
return "wi-day-sunny.png"
else:
return "wi-rain.png"
elif icon == "snow":
if not current:
return "wi-day-snow.png"
return "wi-night-clear.png"
elif icon == 1100:
if not night:
return "wi-day-sunny-overcast.png"
else:
return "wi-snow.png"
elif icon == "sleet":
if not current:
return "wi-day-sleet.png"
return "wi-night-alt-partly-cloudy.png"
elif icon == 1101:
if not night:
return "wi-day-cloudy-high.png"
else:
return "wi-sleet.png"
elif icon == "wind":
if not current:
return "wi-day-windy.png"
return "wi-night-partly-cloudy.png"
elif icon == 1102:
return "wi-cloud.png"
elif icon == 1001:
return "wi-cloudy.png"
elif icon == 1103:
if not night:
return "wi-day-cloudy-high.png"
else:
return "wi-strong-wind.png"
elif icon == "fog":
if not current:
return "night-cloud-high.png"
elif icon == 2000:
return "wi-fog.png"
elif icon == 2100 or icon == 2101 or icon == 2102 or icon == 2103 or icon == 2106 or icon == 2107 or icon == 2108:
if not night:
return "wi-day-fog.png"
else:
return "wi-fog.png"
elif icon == "cloudy":
return "wi-cloudy.png"
elif icon == "partly-cloudy-day":
return "wi-day-cloudy.png"
elif icon == "partly-cloudy-night":
return "wi-night-partly-cloudy.png"
elif icon == "hail":
if not current:
return "wi-night-fog.png"
elif icon == 4000:
return "wi-sprinkle.png"
elif icon == 4000:
return "wi-sprinkle.png"
elif icon == 4200:
return "wi-showers.png"
elif icon == 4001:
return "wi-rain.png"
elif icon == 4201:
return "wi-showers.png"
elif icon == 4203 or icon == 4204 or icon == 4205 or icon == 4213 or icon == 4214 or icon == 4215 or icon == 4209 or icon == 4208 or icon == 4210 or icon == 4211 or icon == 4202 or icon == 4212:
if not night:
return "wi-day-rain.png"
else:
return "wi-night-alt-rain.png"
elif icon == 5001 or icon == 5100 or icon == 5000 or icon == 5101:
return "wi-snow.png"
elif icon == 5115 or icon == 5116:
if not night:
return "wi-day-sleet.png"
else:
return "wi-night-sleet.png"
elif icon == 5122 or icon == 5110 or icon == 5108 or icon == 5114 or icon == 5112:
return "wi-sleet.png"
elif icon == 5103 or icon == 5104 or icon == 5105 or icon == 5106 or icon == 5107 or icon == 5119 or icon == 5120 or icon == 5121:
if not night:
return "wi-day-snow.png"
else:
return "wi-night-snow.png"
elif icon == 6000 or icon == 6200 or icon == 6001 or icon == 6201 or icon == 6204 or icon == 6206 or icon == 6212 or icon == 6220 or icon == 6222:
return "wi-sprinkle.png"
elif icon == 6003 or icon == 6002 or icon == 6004 or icon == 6205 or icon == 6203 or icon == 6209 or icon == 6213 or icon == 6214 or icon == 6215 or icon == 6207 or icon == 6202 or icon == 6208:
if not night:
return "wi-day-sprinkle.png"
else:
return "wi-night-sprinkle.png"
elif icon == 7102 or icon == 7000 or icon == 7101 or icon == 7105 or icon == 7115 or icon == 7117 or icon == 7106 or icon == 7103:
return "wi-hail.png"
elif icon == 7110 or icon == 7111 or icon == 7112 or icon == 7108 or icon == 7107 or icon == 7109 or icon == 7114 or icon == 7116:
if not night:
return "wi-day-hail.png"
else:
return "wi-hail.png"
elif icon == "thunderstorm":
if not current:
return "wi-night-hail.png"
elif icon == 8000:
return "wi-thunderstorm.png"
elif icon == 8001 or icon == 8003 or icon == 8002:
if not night:
return "wi-day-thunderstorm.png"
else:
return "wi-thunderstorm.png"
elif icon == "tornado":
return "wi-tornado.png"
return "wi-night-thunderstorm.png"
else:
return "wi-alien.png"
def get_description(icon, night=False):
if icon == 1000:
if not night:
return "Ensoleillé"
else:
return "Temps clair"
elif icon == 1100:
return "Dégagé"
elif icon == 1101:
return "Partiellement nuageux"
elif icon == 1102:
return "Plutôt nuageux"
elif icon == 1001:
return "Nuageux"
elif icon == 1103:
return "Dégagé et nuageux"
elif icon == 2000:
return "Brouillard"
elif icon == 2100:
return "Brouillard léger"
elif icon == 2101:
return "Brouillard léger et ciel dégagé"
elif icon == 2102:
return "Brouillard léger et ciel partiellement nuageux"
elif icon == 2103:
return "Brouillard léger et ciel plutôt nuageux"
elif icon == 2106:
return "Brouillard et ciel dégagé"
elif icon == 2107:
return "Brouillard et ciel partiellement nuageux"
elif icon == 2108:
return "Brouillard et ciel plutôt nuageux"
elif icon == 4000:
return "Bruine"
elif icon == 4200:
return "Pluie légère"
elif icon == 4001:
return "Pluie"
elif icon == 4201:
return "Forte pluie"
elif icon == 4203:
return "Bruine et ciel dégagé"
elif icon == 4204:
return "Bruine et ciel partiellement nuageux"
elif icon == 4205:
return "Bruine et ciel plutôt nuageux"
elif icon == 4213:
return "Averse et ciel dégagé"
elif icon == 4214:
return "Averse et ciel partiellement nuageux"
elif icon == 4215:
return "Averse et ciel plutôt nuageux"
elif icon == 4209:
return "Pluie et ciel dégagé"
elif icon == 4208:
return "Pluie et ciel partiellement nuageux"
elif icon == 4210:
return "Pluie et ciel plutôt nuageux"
elif icon == 4211:
return "Pluie forte et ciel dégagé"
elif icon == 4202:
return "Pluie forte et ciel partiellement nuageux"
elif icon == 4212:
return "Pluie forte et ciel plutôt nuageux"
elif icon == 5001:
return "Quelques flocons"
elif icon == 5100:
return "Neige légère"
elif icon == 5000:
return "Neige"
elif icon == 5101:
return "Tempête de neige"
elif icon == 5115:
return "Quelques flocons et ciel dégagé"
elif icon == 5116:
return "Quelques flocons et ciel partiellement nuageux"
elif icon == 5117:
return "Quelques flocons et ciel plutôt nuageux"
elif icon == 5122:
return "Bruine et quelques flocons"
elif icon == 5102:
return "Neige légère et ciel dégagé"
elif icon == 5103:
return "Neige légère et ciel partiellement nuageux"
elif icon == 5104:
return "Neige légère et ciel plutôt nuageux"
elif icon == 5105:
return "Neige et ciel dégagé"
elif icon == 5106:
return "Neige et ciel partiellement nuageux"
elif icon == 5107:
return "Neige et ciel plutôt nuageux"
elif icon == 5119:
return "Neige abondante et ciel dégagé"
elif icon == 5120:
return "Neige abondante et ciel partiellement nuageux"
elif icon == 5121:
return "Neige abondante et ciel plutôt nuageux"
elif icon == 5110:
return "Bruine et neige"
elif icon == 5108:
return "Pluie et neige"
elif icon == 5114:
return "Neige et pluie verglaçante"
elif icon == 5112:
return "Neige et grèle"
elif icon == 6000:
return "Bruine verglaçante"
elif icon == 6200:
return "Légère bruine verglaçante"
elif icon == 6001:
return "Pluie verglaçante"
elif icon == 6201:
return "Pluie forte verglaçante"
elif icon == 6003:
return "Bruine verglaçante et ciel dégagé"
elif icon == 6002:
return "Bruine verglaçante et ciel partiellement nuageux"
elif icon == 6004:
return "Bruine verglaçante et ciel plutôt nuageux"
elif icon == 6204:
return "Bruine verglaçante et bruine"
elif icon == 6206:
return "Bruine verglaçante et pluie légère"
elif icon == 6205:
return "Averse verglaçante et ciel dégagé"
elif icon == 6203:
return "Averse verglaçante et ciel partiellement nuageux"
elif icon == 6209:
return "Averse verglaçante et ciel plutôt nuageux"
elif icon == 6213:
return "Pluie verglaçante et ciel dégagé"
elif icon == 6214:
return "Pluie verglaçante et ciel partiellement nuageux"
elif icon == 6215:
return "Pluie verglaçante et ciel plutôt nuageux"
elif icon == 6212:
return "Pluie verglaçante et bruine"
elif icon == 6220:
return "Pluie verglaçante et pluie légère"
elif icon == 6222:
return "Averses et pluie verglaçante"
elif icon == 6207:
return "Pluie forte verglaçante et ciel dégagé"
elif icon == 6202:
return "Pluie forte verglaçante et ciel partiellement nuageux"
elif icon == 6208:
return "Pluie forte verglaçante et ciel plutôt nuageux"
elif icon == 7000:
return "Grèle"
elif icon == 7102:
return "Grèle légère"
elif icon == 7101:
return "Forte grèle"
elif icon == 7110:
return "Grèle légère et ciel dégagé"
elif icon == 7111:
return "Grèle légère et ciel partiellement nuageux"
elif icon == 7112:
return "Grèle légère et ciel plutôt nuageux"
elif icon == 7108:
return "Grèle et ciel dégagé"
elif icon == 7107:
return "Grèle et ciel partiellement nuageux"
elif icon == 7109:
return "Grèle et ciel plutôt nuageux"
elif icon == 7113:
return "Grèle forte et ciel dégagé"
elif icon == 7114:
return "Grèle forte et ciel partiellement nuageux"
elif icon == 7116:
return "Grèle forte et ciel plutôt nuageux"
elif icon == 7105:
return "Bruine et grèle"
elif icon == 7115:
return "Pluie légère et grèle"
elif icon == 7117:
return "Pluie et grèle"
elif icon == 7106:
return "Pluie verglaçante et grèle"
elif icon == 7103:
return "Pluie verglaçante et grèle forte"
elif icon == 8000:
return "Orageux"
elif icon == 8001:
return "Orage et ciel dégagé"
elif icon == 8003:
return "Orage et ciel partiellement nuageux"
elif icon == 8002:
return "Orage et ciel plutôt nuageux"
else:
return "Invasion d'aliens ?"
def get_moon_icon(self, day=0):
moon_phase = self.get_daily()["data"][day]["moonPhase"]
@ -161,15 +390,15 @@ class DarkSkyAPI:
def get_currently(self, *args, **kwargs):
return self.get_weather(*args, **kwargs)["currently"]
return self.get_weather("realtime", *args, **kwargs)["data"]["values"]
def get_hourly(self, *args, **kwargs):
return self.get_weather(*args, **kwargs)["hourly"]
return self.get_weather(*args, **kwargs)["timelines"]["hourly"]
def get_daily(self, *args, **kwargs):
return self.get_weather(*args, **kwargs)["daily"]
return self.get_weather(*args, **kwargs)["timelines"]["daily"]
def has_alerts(self, *args, **kwargs):
return "alerts" in self.get_weather(*args, **kwargs) and len(self.get_weather(*args, **kwargs)["alerts"]) > 0
@ -178,14 +407,13 @@ class DarkSkyAPI:
return self.get_weather(*args, **kwargs)["alerts"]
def read_timestamp(self, timestamp, *args, **kwargs):
wth = self.get_weather(*args, **kwargs)
tz = timezone(timedelta(hours=wth["offset"]), wth["timezone"])
return datetime.fromtimestamp(timestamp, tz=tz)
PARIS = ZoneInfo("Europe/Paris")
return datetime.fromisoformat(timestamp.replace("Z", "+00:00")).astimezone(PARIS)
WeatherAPI = DarkSkyAPI
WeatherAPI = TomorrowAPI
if __name__ == '__main__':
dsa = DarkSkyAPI()
dsa = TomorrowAPI()
print(dsa.get_currently())
print(dsa.get_daily())