Added air quality and precipitation information to clock face

This commit is contained in:
Admar Schoonen 2023-05-26 22:54:30 +02:00
parent c52c355299
commit 1d89488f3a
1 changed files with 152 additions and 10 deletions

162
clock.py
View File

@ -12,6 +12,7 @@ import time
from sounds import WakeUpSounds
import json
from hsluv import hsluv_to_rgb, rgb_to_hsluv
import requests
def is_arm():
if (uname()[4][:3] == 'arm') or (uname()[4][:7] == 'aarch64'):
@ -267,6 +268,81 @@ class MyClockWidget(FloatLayout):
is_arm = is_arm()
aqi_colors = [
[0.0, 0.0, 0.0], # x < 1.0 black (good)
[0.0, 0.0, 255.0/255.0], # 1.0 <= x < 2.0 blue (good)
[0.0, 160.0/255.0, 160.0/255.0], # 2.0 <= x < 3.0 cyan (good)
[1.0, 1.0, 1.0], # 3.0 <= x < 4.0 white (mediocre)
[255.0/255.0, 255.0/255.0, 150.0/255.0], # 4.0 <= < x 5.0 light yellow (mediocre)
[200.0/255.0, 200.0/255.0, 0.0], # 5.0 <= x < 6.0 yellow (mediocre)
[1.0, 175.0/255.0, 0.0], # 6.0 <= x < 7.0 orange (inadequate)
[1.0, 120.0/255.0, 0.0], # 7.0 <= x < 8.0 red orange (inadequate)
[200.0/255.0, 0.0, 0.0], # 8.0 <= x < 9.0 red (bad)
[200.0/255.0, 0.0, 200.0/255.0], # 9.0 <= x < 10.0 magenta (bad)
[70.0/255.0, 0.0, 255.0/255.0], # 10.0 <= x purple (terrible)
]
rain = []
rain_thresholds = [0.1, 0.22, 0.47, 1.0, 2.2, 4.7, 10, 22, 47, 100]
pollen = []
pollen_thresholds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
aqi = []
aqi_thresholds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
paqi = []
paqi_thresholds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
uvi = []
uvi_thresholds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
def get_air_quality(self, *args):
response = requests.get("https://sinoptik.luon.net/forecast?address=telefoonstraat%2018,%20eindhoven&metrics=precipitation&metrics=UVI&metrics=AQI&metrics=pollen&metrics=PAQI")
self.rain = []
self.pollen = []
self.aqi = []
self.paqi = []
self.uvi = []
if response.status_code == 200:
t = datetime.datetime.now().timestamp()
j = json.loads(response.text)
try:
for i in j["precipitation"]:
if i["time"]>= t - 300:
self.rain.append(i["value"])
except:
print("Couldn't find precipitation")
try:
for i in j["pollen"]:
if i["time"] >= t - 3600:
self.pollen.append(i["value"])
except:
print("Couldn't find pollen")
try:
for i in j["AQI"]:
if i["time"] >= t - 3600:
self.aqi.append(i["value"])
except:
print("Couldn't find AQI")
try:
for i in j["PAQI"]:
if i["time"] >= t - 3600:
self.paqi.append(i["value"])
except:
print("Couldn't find PAQI")
try:
for i in j["UVI"]:
if i["time"] >= t - 24 * 3600:
self.uvi.append(i["value"])
except:
print("Couldn't find UVI")
else:
print("Error retrieving air quality; got response " + str(response))
def update_background_automatic_sunrise(self):
background = self.ids["background"]
self.draw_list_curr_frame.append(["canvas.clear()", background])
@ -487,7 +563,7 @@ class MyClockWidget(FloatLayout):
widget.saved_attrs = widget.height, widget.size_hint_y, widget.opacity, widget.disabled
widget.height, widget.size_hint_y, widget.opacity, widget.disabled = 0, None, 0, True
def draw_face(self):
def draw_numbers(self):
"""
Add number labels when added in widget hierarchy
"""
@ -515,6 +591,63 @@ class MyClockWidget(FloatLayout):
))
self.ids["face"].add_widget(self.face_numbers[i - 1])
def draw_rain_expectation(self):
if len(self.rain) == 0:
return
face_plate = self.ids["face_plate"]
with face_plate.canvas:
for i in range(0, 12):
idx = 0
for l in self.rain_thresholds:
if l > self.rain[i]:
break
idx = idx + 1
if idx >= len(self.aqi_colors):
idx = len(self.aqi_colors) - 1
color = self.aqi_colors[idx]
if color != [0.0, 0.0, 0.0]:
self.draw_list_curr_frame.append(["Color", face_plate.canvas, color[0], color[1], color[2]])
R = face_plate.size[0] / 2
r = R / 10
x = 0.5 + 0.45*math.sin(2 * math.pi * i/12)
y = 0.5 + 0.45*math.cos(2 * math.pi * i/12)
p = [face_plate.pos[0] + 2 * R * x - r, face_plate.pos[1] + 2 * R * y - r]
#self.draw_list_curr_frame.append(["Circle", face_plate.canvas, p, r / 10])
self.draw_list_curr_frame.append(["Ellipse", face_plate.canvas, [2 * r, 2 * r], p])
def draw_aqi_expectation(self):
if len(self.paqi) == 0:
return
face_plate = self.ids["face_plate"]
with face_plate.canvas:
for i in range(0, 12):
idx = 0
for l in self.paqi_thresholds:
if l > self.paqi[i]:
break
idx = idx + 1
if idx >= len(self.aqi_colors):
idx = len(self.aqi_colors) - 1
color = self.aqi_colors[idx]
if color != [0.0, 0.0, 0.0]:
self.draw_list_curr_frame.append(["Color", face_plate.canvas, color[0], color[1], color[2]])
R = face_plate.size[0] / 2
r = R / 10
x = 0.5 + 0.30*math.sin(2 * math.pi * i/12)
y = 0.5 + 0.30*math.cos(2 * math.pi * i/12)
p = [face_plate.pos[0] + 2 * R * x - r, face_plate.pos[1] + 2 * R * y - r]
#self.draw_list_curr_frame.append(["Circle", face_plate.canvas, p, r / 10])
self.draw_list_curr_frame.append(["Ellipse", face_plate.canvas, [2 * r, 2 * r], p])
def draw_face(self):
self.draw_numbers()
def update_theme(self):
if self.settings.theme_selected == "Automatic":
self.apply_theme()
@ -527,7 +660,7 @@ class MyClockWidget(FloatLayout):
self.draw_list_curr_frame.append(["Color", face_plate.canvas, color[0], color[1], color[2]])
r = face_plate.size[0] / 2
p = [face_plate.pos[0] + r, face_plate.pos[1] + r]
self.draw_list_curr_frame.append(["Circle", face_plate.canvas, p, r])
#self.draw_list_curr_frame.append(["Circle", face_plate.canvas, p, r])
#self.draw_list_curr_frame.append(["Ellipse", face_plate.canvas, face_plate.size, face_plate.pos])
if self.view == "set_alarm":
@ -535,15 +668,21 @@ class MyClockWidget(FloatLayout):
else:
t = datetime.datetime.now()
for i in range(0, 12):
if t.hour < 12:
offset = 0
else:
offset = 12
self.face_numbers[i].color = self.theme.color_numbers
self.face_numbers[i].text = str(i + 1 + offset)
if self.view == "clock":
for i in range(0, 12):
self.face_numbers[i].text = ""
self.draw_rain_expectation()
self.draw_aqi_expectation()
else:
for i in range(0, 12):
if t.hour < 12:
offset = 0
else:
offset = 12
self.face_numbers[i].color = self.theme.color_numbers
self.face_numbers[i].text = str(i + 1 + offset)
def on_parent(self, myclock, parent):
self.draw_face()
@ -1437,6 +1576,9 @@ class MyApp(App):
# then update at update_rate times per second
Clock.schedule_interval(clock_widget.update_display, 1.0/update_rate)
Clock.schedule_once(clock_widget.get_air_quality, 0)
Clock.schedule_interval(clock_widget.get_air_quality, 60)
if is_arm():
Window.borderless = True