Added air quality and precipitation information to clock face
This commit is contained in:
parent
c52c355299
commit
1d89488f3a
162
clock.py
162
clock.py
|
@ -12,6 +12,7 @@ import time
|
||||||
from sounds import WakeUpSounds
|
from sounds import WakeUpSounds
|
||||||
import json
|
import json
|
||||||
from hsluv import hsluv_to_rgb, rgb_to_hsluv
|
from hsluv import hsluv_to_rgb, rgb_to_hsluv
|
||||||
|
import requests
|
||||||
|
|
||||||
def is_arm():
|
def is_arm():
|
||||||
if (uname()[4][:3] == 'arm') or (uname()[4][:7] == 'aarch64'):
|
if (uname()[4][:3] == 'arm') or (uname()[4][:7] == 'aarch64'):
|
||||||
|
@ -267,6 +268,81 @@ class MyClockWidget(FloatLayout):
|
||||||
|
|
||||||
is_arm = is_arm()
|
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):
|
def update_background_automatic_sunrise(self):
|
||||||
background = self.ids["background"]
|
background = self.ids["background"]
|
||||||
self.draw_list_curr_frame.append(["canvas.clear()", 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.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
|
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
|
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])
|
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):
|
def update_theme(self):
|
||||||
if self.settings.theme_selected == "Automatic":
|
if self.settings.theme_selected == "Automatic":
|
||||||
self.apply_theme()
|
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]])
|
self.draw_list_curr_frame.append(["Color", face_plate.canvas, color[0], color[1], color[2]])
|
||||||
r = face_plate.size[0] / 2
|
r = face_plate.size[0] / 2
|
||||||
p = [face_plate.pos[0] + r, face_plate.pos[1] + r]
|
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])
|
#self.draw_list_curr_frame.append(["Ellipse", face_plate.canvas, face_plate.size, face_plate.pos])
|
||||||
|
|
||||||
if self.view == "set_alarm":
|
if self.view == "set_alarm":
|
||||||
|
@ -535,15 +668,21 @@ class MyClockWidget(FloatLayout):
|
||||||
else:
|
else:
|
||||||
t = datetime.datetime.now()
|
t = datetime.datetime.now()
|
||||||
|
|
||||||
for i in range(0, 12):
|
if self.view == "clock":
|
||||||
if t.hour < 12:
|
for i in range(0, 12):
|
||||||
offset = 0
|
self.face_numbers[i].text = ""
|
||||||
else:
|
|
||||||
offset = 12
|
|
||||||
|
|
||||||
self.face_numbers[i].color = self.theme.color_numbers
|
|
||||||
self.face_numbers[i].text = str(i + 1 + offset)
|
|
||||||
|
|
||||||
|
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):
|
def on_parent(self, myclock, parent):
|
||||||
self.draw_face()
|
self.draw_face()
|
||||||
|
@ -1437,6 +1576,9 @@ class MyApp(App):
|
||||||
# then update at update_rate times per second
|
# then update at update_rate times per second
|
||||||
Clock.schedule_interval(clock_widget.update_display, 1.0/update_rate)
|
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():
|
if is_arm():
|
||||||
Window.borderless = True
|
Window.borderless = True
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue