|
|
|
@ -13,6 +13,7 @@ from weather_au import api
|
|
|
|
|
DIRECTORY = os.path.dirname(os.path.realpath(__file__))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PiWeather:
|
|
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
@ -123,6 +124,7 @@ class PiWeather:
|
|
|
|
|
Returns:
|
|
|
|
|
str -- Returns HH:MM in 24 format
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
sun_time = datetime.fromisoformat(suntime.split("Z")[0])
|
|
|
|
|
local_time = self.convert_local(sun_time)
|
|
|
|
|
return str(local_time.hour)+":"+str(local_time.minute)
|
|
|
|
@ -132,7 +134,7 @@ class PiWeather:
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
general_data = self.weather.observations()
|
|
|
|
|
forecast_rain = self.weather.forecast_rain()
|
|
|
|
|
#forecast_rain = self.weather.forecast_rain()
|
|
|
|
|
forecast_daily = self.weather.forecasts_daily()
|
|
|
|
|
try:
|
|
|
|
|
self.lookup = {
|
|
|
|
@ -142,16 +144,24 @@ class PiWeather:
|
|
|
|
|
"speed": general_data["wind"]["speed_kilometre"],
|
|
|
|
|
"direction": general_data["wind"]["direction"]
|
|
|
|
|
},
|
|
|
|
|
"chance": "{}%".format(forecast_rain['chance']),
|
|
|
|
|
"uvindex": forecast_daily[0]["uv"]["category"],
|
|
|
|
|
"chance": "{}%".format(forecast_daily[0]["rain"]["chance"]),
|
|
|
|
|
"chance_tom": "{}%".format(forecast_daily[1]["rain"]["chance"]),
|
|
|
|
|
"uvindex": forecast_daily[0]["uv"],
|
|
|
|
|
"uvindex_tom": forecast_daily[1]["uv"],
|
|
|
|
|
"sunrise": self.get_suntime(forecast_daily[0]["astronomical"]["sunrise_time"]),
|
|
|
|
|
"sunrise_tom": self.get_suntime(forecast_daily[1]["astronomical"]["sunrise_time"]),
|
|
|
|
|
"sunset": self.get_suntime(forecast_daily[0]["astronomical"]["sunset_time"]),
|
|
|
|
|
"sunset_tom": self.get_suntime(forecast_daily[1]["astronomical"]["sunset_time"]),
|
|
|
|
|
"weather_type": forecast_daily[0]["short_text"],
|
|
|
|
|
"weather_type_tom": forecast_daily[1]["short_text"],
|
|
|
|
|
"weather_code": forecast_daily[0]["icon_descriptor"],
|
|
|
|
|
"fire": forecast_daily[0]["fire_danger"],
|
|
|
|
|
"fire_tom": forecast_daily[1]["fire_danger"],
|
|
|
|
|
"forecast": forecast_daily
|
|
|
|
|
}
|
|
|
|
|
print(self.lookup["forecast"])
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print("ERROR: {}".format(e))
|
|
|
|
|
print(f"ERROR: {e}")
|
|
|
|
|
|
|
|
|
|
def get_fact(self):
|
|
|
|
|
api = "https://uselessfacts.jsph.pl/random.json?language=en"
|
|
|
|
@ -210,10 +220,8 @@ class PiDisplay(PiWeather):
|
|
|
|
|
self.display.AddImg(self.which_icon(self.unknown_icon), 133, 66, (32, 32), Id="ForecastIconFive")
|
|
|
|
|
self.display.AddImg(self.which_icon(self.unknown_icon), 166, 66, (32, 32), Id="ForecastIconSix")
|
|
|
|
|
else:
|
|
|
|
|
self.display.AddText("Today: ...", 25, 51,
|
|
|
|
|
size=15, Id="ForecastOne")
|
|
|
|
|
self.display.AddText("Tomorrow: ...", 25,
|
|
|
|
|
74, size=15, Id="ForecastTwo")
|
|
|
|
|
self.display.AddText("Today: ...", 25, 51, size=15, Id="ForecastOne")
|
|
|
|
|
self.display.AddText("Tomorrow: ...", 25, 77, size=15, Id="ForecastTwo")
|
|
|
|
|
|
|
|
|
|
self.display.AddImg(self.which_icon(self.unknown_icon), 1, 53, (23, 23), Id="ForecastIconOne")
|
|
|
|
|
self.display.AddImg(self.which_icon(self.unknown_icon), 1, 75, (23, 23), Id="ForecastIconTwo")
|
|
|
|
@ -238,7 +246,7 @@ class PiDisplay(PiWeather):
|
|
|
|
|
try:
|
|
|
|
|
self.get_weather()
|
|
|
|
|
self.gotWeather = True
|
|
|
|
|
except Exception:
|
|
|
|
|
except:
|
|
|
|
|
sleep(60)
|
|
|
|
|
|
|
|
|
|
if not self.lookup:
|
|
|
|
@ -246,8 +254,7 @@ class PiDisplay(PiWeather):
|
|
|
|
|
exit()
|
|
|
|
|
|
|
|
|
|
self.display.UpdateImg("WeatherIcon", self.which_icon(str(self.lookup["weather_code"])+".png"))
|
|
|
|
|
self.display.UpdateText("LineOne", self.lookup["weather_type"],
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
self.display.UpdateText("LineOne", self.lookup["weather_type"], fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
self.display.UpdateText("LineFive", "{}".format(self.get_fact()))
|
|
|
|
|
|
|
|
|
|
if self.config["forecast"]["enabled"]:
|
|
|
|
@ -265,88 +272,131 @@ class PiDisplay(PiWeather):
|
|
|
|
|
self.display.UpdateText(
|
|
|
|
|
"ForecastSix", self.get_day(self.lookup["forecast"][6]["date"]))
|
|
|
|
|
|
|
|
|
|
self.display.UpdateImg(
|
|
|
|
|
"ForecastIconOne",
|
|
|
|
|
self.which_icon(str(self.lookup["forecast"][1]["icon_descriptor"])+'.png'))
|
|
|
|
|
self.display.UpdateImg(
|
|
|
|
|
"ForecastIconTwo",
|
|
|
|
|
self.which_icon(str(self.lookup["forecast"][2]["icon_descriptor"])+'.png'))
|
|
|
|
|
self.display.UpdateImg(
|
|
|
|
|
"ForecastIconThree",
|
|
|
|
|
self.which_icon(str(self.lookup["forecast"][3]["icon_descriptor"])+'.png'))
|
|
|
|
|
self.display.UpdateImg(
|
|
|
|
|
"ForecastIconFour",
|
|
|
|
|
self.which_icon(str(self.lookup["forecast"][4]["icon_descriptor"])+'.png'))
|
|
|
|
|
self.display.UpdateImg(
|
|
|
|
|
"ForecastIconFive",
|
|
|
|
|
self.which_icon(str(self.lookup["forecast"][5]["icon_descriptor"])+'.png'))
|
|
|
|
|
self.display.UpdateImg(
|
|
|
|
|
"ForecastIconSix",
|
|
|
|
|
self.which_icon(str(self.lookup["forecast"][6]["icon_descriptor"])+'.png'))
|
|
|
|
|
self.display.UpdateImg("ForecastIconOne", self.which_icon(str(self.lookup["forecast"][1]["icon_descriptor"])+'.png'))
|
|
|
|
|
self.display.UpdateImg("ForecastIconTwo", self.which_icon(str(self.lookup["forecast"][2]["icon_descriptor"])+'.png'))
|
|
|
|
|
self.display.UpdateImg("ForecastIconThree", self.which_icon(str(self.lookup["forecast"][3]["icon_descriptor"])+'.png'))
|
|
|
|
|
self.display.UpdateImg("ForecastIconFour", self.which_icon(str(self.lookup["forecast"][4]["icon_descriptor"])+'.png'))
|
|
|
|
|
self.display.UpdateImg("ForecastIconFive", self.which_icon(str(self.lookup["forecast"][5]["icon_descriptor"])+'.png'))
|
|
|
|
|
self.display.UpdateImg("ForecastIconSix", self.which_icon(str(self.lookup["forecast"][6]["icon_descriptor"])+'.png'))
|
|
|
|
|
else:
|
|
|
|
|
self.display.UpdateText(
|
|
|
|
|
"ForecastOne", "Today: "+self.lookup["forecast"][0]["short_text"])
|
|
|
|
|
self.display.UpdateText(
|
|
|
|
|
"ForecastTwo", "Tomorrow: "+self.lookup["forecast"][1]["short_text"])
|
|
|
|
|
|
|
|
|
|
self.display.UpdateImg(
|
|
|
|
|
"ForecastIconOne",
|
|
|
|
|
self.which_icon(str(self.lookup["forecast"][1]["icon_descriptor"])+'.png'))
|
|
|
|
|
self.display.UpdateImg(
|
|
|
|
|
"ForecastIconTwo",
|
|
|
|
|
self.which_icon(str(self.lookup["forecast"][2]["icon_descriptor"])+'.png'))
|
|
|
|
|
|
|
|
|
|
for stat in self.order:
|
|
|
|
|
if stat == "temperature":
|
|
|
|
|
self.display.UpdateText(
|
|
|
|
|
"LineTwo", "Now Temp: "+self.lookup[stat],
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
self.display.UpdateText(
|
|
|
|
|
"LineThree", "Low: {} -> High: {}".format(
|
|
|
|
|
self.lookup["forecast"][0]["temp_min"], self.lookup["forecast"][0]["temp_max"]),
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
elif stat == "chance":
|
|
|
|
|
if self.lookup[stat] == "None%":
|
|
|
|
|
rain_chance = '0%'
|
|
|
|
|
else:
|
|
|
|
|
rain_chance = self.lookup[stat]
|
|
|
|
|
self.display.UpdateText("LineTwo", "Rain Chance",
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
self.display.UpdateText("LineThree", rain_chance,
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
if int(rain_chance[:-1]) > 40:
|
|
|
|
|
self.display.UpdateText("LineFive", "Umbrealla Today")
|
|
|
|
|
elif stat == "humidity":
|
|
|
|
|
self.display.UpdateText(
|
|
|
|
|
"LineTwo", "Humidity: "+self.lookup[stat],
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
humidity = int(self.lookup[stat][:-1])
|
|
|
|
|
scale = ""
|
|
|
|
|
if humidity < 5:
|
|
|
|
|
scale = "Arid Desert"
|
|
|
|
|
elif humidity < 25:
|
|
|
|
|
scale = "It\'s a dry heat"
|
|
|
|
|
elif humidity < 60:
|
|
|
|
|
scale = "Dry"
|
|
|
|
|
elif humidity < 80:
|
|
|
|
|
scale = "It\'s pretty humid"
|
|
|
|
|
if self.lookup["forecast"][0]["temp_min"] is None:
|
|
|
|
|
self.display.UpdateText(
|
|
|
|
|
"ForecastOne", self.get_day(self.lookup["forecast"][1]["date"])+": "+self.lookup["forecast"][1]["short_text"])
|
|
|
|
|
self.display.UpdateText(
|
|
|
|
|
"ForecastTwo", self.get_day(self.lookup["forecast"][2]["date"])+": "+self.lookup["forecast"][2]["short_text"])
|
|
|
|
|
self.display.UpdateImg("ForecastIconOne", self.which_icon(str(self.lookup["forecast"][1]["icon_descriptor"])+'.png'))
|
|
|
|
|
self.display.UpdateImg("ForecastIconTwo", self.which_icon(str(self.lookup["forecast"][2]["icon_descriptor"])+'.png'))
|
|
|
|
|
else:
|
|
|
|
|
scale = "HUMID AF"
|
|
|
|
|
self.display.UpdateText("LineThree", scale,
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
elif stat == "wind":
|
|
|
|
|
self.display.UpdateText(
|
|
|
|
|
"LineTwo", "Speed: {}".format(self.lookup[stat]["speed"]))
|
|
|
|
|
self.display.UpdateText(
|
|
|
|
|
"LineThree", "Direction: {}".format(self.lookup[stat]["direction"]))
|
|
|
|
|
elif stat == "uvindex":
|
|
|
|
|
self.display.UpdateText("LineTwo", "UV Index")
|
|
|
|
|
self.display.UpdateText("LineThree", self.lookup[stat])
|
|
|
|
|
elif stat == "sun":
|
|
|
|
|
self.display.UpdateText("LineTwo", "Sunrise || Sunset")
|
|
|
|
|
self.display.UpdateText("LineThree", "{} || {}".format(self.lookup["sunrise"], self.lookup["sunset"]))
|
|
|
|
|
|
|
|
|
|
self.display.WriteAll()
|
|
|
|
|
self.display.UpdateText(
|
|
|
|
|
"ForecastOne", "Today: "+self.lookup["forecast"][0]["short_text"])
|
|
|
|
|
self.display.UpdateText(
|
|
|
|
|
"ForecastTwo", "Tomorrow: "+self.lookup["forecast"][1]["short_text"])
|
|
|
|
|
self.display.UpdateImg("ForecastIconOne", self.which_icon(str(self.lookup["forecast"][0]["icon_descriptor"])+'.png'))
|
|
|
|
|
self.display.UpdateImg("ForecastIconTwo", self.which_icon(str(self.lookup["forecast"][1]["icon_descriptor"])+'.png'))
|
|
|
|
|
for stat in self.order:
|
|
|
|
|
# Bom sets "temp_min" to null when its near night-time so use that and get the tonight/tomorrow information
|
|
|
|
|
# "Tomorrow"
|
|
|
|
|
if self.lookup["forecast"][0]["temp_min"] is None:
|
|
|
|
|
if stat == "temperature":
|
|
|
|
|
self.display.UpdateText("LineTwo", "Night Min: "+str(self.lookup["forecast"][0]["now"]["temp_now"]),
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
self.display.UpdateText("LineThree", "Tomorrow Max: "+str(self.lookup["forecast"][0]["now"]["temp_later"]),
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
elif stat == "chance":
|
|
|
|
|
if str(self.lookup["chance_tom"]) == "None":
|
|
|
|
|
rain_chance = '0%'
|
|
|
|
|
else:
|
|
|
|
|
rain_chance = "{}".format(self.lookup["chance_tom"])
|
|
|
|
|
max_rain = "{}{}".format(
|
|
|
|
|
self.lookup["forecast"][1]["rain"]["amount"]["max"],
|
|
|
|
|
self.lookup["forecast"][1]["rain"]["amount"]["units"])
|
|
|
|
|
self.display.UpdateText("LineTwo", "Tommorow Rain:",
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
self.display.UpdateText(
|
|
|
|
|
"LineThree",
|
|
|
|
|
"{} with {}".format(rain_chance, max_rain),
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
self.display.UpdateText(
|
|
|
|
|
"LineFour",
|
|
|
|
|
"Take an Umbrella Tomorrow!",
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
elif stat == "sun":
|
|
|
|
|
self.display.UpdateText("LineTwo", "Sunrise Tomorrow: {}".format(self.lookup["sunrise_tom"]))
|
|
|
|
|
self.display.UpdateText("LineThree", "Sunset Tomorrow: {}".format(self.lookup["sunset_tom"]))
|
|
|
|
|
elif stat == "uv_fire":
|
|
|
|
|
self.display.UpdateText("LineTwo", "UV Tomorrow: "+self.lookup["uvindex_tom"]["category"])
|
|
|
|
|
self.display.UpdateText("LineThree", "Fire Danger Tom: "+self.lookup["fire_tom"])
|
|
|
|
|
if self.lookup["uvindex_tom"]["max_index"] > 16:
|
|
|
|
|
self.display.UpdateText("LineFour", "!!! You NEED Sunscreen !!!",
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
elif stat == "humid_wind":
|
|
|
|
|
# Can't get tomorrow's humidity... show now... no-one will notice
|
|
|
|
|
humidity = int(self.lookup["humidity"][:-1])
|
|
|
|
|
scale = ""
|
|
|
|
|
if humidity < 5:
|
|
|
|
|
scale = "Arid Desert"
|
|
|
|
|
elif humidity < 25:
|
|
|
|
|
scale = "Dry heat"
|
|
|
|
|
elif humidity < 60:
|
|
|
|
|
scale = "Average Humid"
|
|
|
|
|
elif humidity < 80:
|
|
|
|
|
scale = "H: Pretty humid"
|
|
|
|
|
else:
|
|
|
|
|
scale = "HUMID AF"
|
|
|
|
|
self.display.UpdateText(
|
|
|
|
|
"LineTwo", "{}: {}".format(scale, self.lookup["humidity"]),
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
self.display.UpdateText(
|
|
|
|
|
"LineThree", "Speed: {} | Dir: {}".format(self.lookup["wind"]["speed"], self.lookup["wind"]["direction"]))
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
# Its Morning we care about Today
|
|
|
|
|
if stat == "temperature":
|
|
|
|
|
self.display.UpdateText("LineTwo", "Now Temp: "+self.lookup[stat],
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
self.display.UpdateText(
|
|
|
|
|
"LineThree", "Low: {} -> High: {}".format(self.lookup["forecast"][0]["temp_min"], self.lookup["forecast"][0]["temp_max"]),
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
elif stat == "chance":
|
|
|
|
|
if self.lookup[stat] == "None%":
|
|
|
|
|
rain_chance = '0%'
|
|
|
|
|
else:
|
|
|
|
|
rain_chance = self.lookup[stat]
|
|
|
|
|
self.display.UpdateText("LineTwo", "Rain Chance",
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
self.display.UpdateText("LineThree", rain_chance,
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
if int(rain_chance[:-1]) > 40:
|
|
|
|
|
self.display.UpdateText("LineFive", "Umbrealla Today")
|
|
|
|
|
elif stat == "humid_wind":
|
|
|
|
|
humidity = int(self.lookup[stat][:-1])
|
|
|
|
|
scale = ""
|
|
|
|
|
if humidity < 5:
|
|
|
|
|
scale = "Arid Desert"
|
|
|
|
|
elif humidity < 25:
|
|
|
|
|
scale = "Dry heat"
|
|
|
|
|
elif humidity < 60:
|
|
|
|
|
scale = "Average Humid"
|
|
|
|
|
elif humidity < 80:
|
|
|
|
|
scale = "H: Pretty humid"
|
|
|
|
|
else:
|
|
|
|
|
scale = "HUMID AF"
|
|
|
|
|
self.display.UpdateText(
|
|
|
|
|
"LineTwo", "{}: "+self.lookup[stat],
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
self.display.UpdateText(
|
|
|
|
|
"LineThree", "Speed: {} | Dir: {}".format(self.lookup[stat]["speed"], self.lookup[stat]["direction"]))
|
|
|
|
|
elif stat == "uv_fire":
|
|
|
|
|
self.display.UpdateText("LineTwo", "UV Index: "+self.lookup["uvindex"]["category"])
|
|
|
|
|
self.display.UpdateText("LineThree", "Fire Danger: "+self.lookup["fire"])
|
|
|
|
|
if self.lookup["uvindex"]["max_index"] > 16:
|
|
|
|
|
self.display.UpdateText("LineFour", "!!! You NEED Sunscreen !!!",
|
|
|
|
|
fontPath='/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf')
|
|
|
|
|
elif stat == "sun":
|
|
|
|
|
self.display.UpdateText("LineTwo", "Sunrise: {}".format(self.lookup["sunrise"]))
|
|
|
|
|
self.display.UpdateText("LineThree", "Sunset: {}".format(self.lookup["sunset"]))
|
|
|
|
|
|
|
|
|
|
self.display.WriteAll(partialUpdate=True)
|
|
|
|
|
if len(self.order) >= 3:
|
|
|
|
|
sleep(20)
|
|
|
|
|
else:
|
|
|
|
@ -356,10 +406,8 @@ class PiDisplay(PiWeather):
|
|
|
|
|
|
|
|
|
|
def which_icon(self, icon_code):
|
|
|
|
|
"""If the icon does not exist, it defaults to Unknown
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Argument: codename
|
|
|
|
|
|
|
|
|
|
Return: str for image
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
@ -372,7 +420,6 @@ class PiDisplay(PiWeather):
|
|
|
|
|
print(e)
|
|
|
|
|
return os.path.join(DIRECTORY, 'images', 'weather', str(self.unknown_icon))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PI = PiDisplay()
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|