diff --git a/clock.py b/clock.py index 6cbcfb3..5276af7 100644 --- a/clock.py +++ b/clock.py @@ -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