X-Git-Url: https://zdv2.bktei.com/gitweb/EVA-2020-02-2.git/blobdiff_plain/2fe226f8a1755e1cf487c972b56b9166b4f2ff4b..12ec16a8c88c5a13ef2fe79b4505f69f021ec7cf:/examples/weather-and-light.py diff --git a/examples/weather-and-light.py b/examples/weather-and-light.py old mode 100644 new mode 100755 index a0d755d..cd8ae96 --- a/examples/weather-and-light.py +++ b/examples/weather-and-light.py @@ -1,3 +1,9 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +f"Sorry! This program requires Python >= 3.6 😅" + +import os import time import numpy import colorsys @@ -9,7 +15,9 @@ from bme280 import BME280 from ltr559 import LTR559 import pytz -from astral import Astral +from pytz import timezone +from astral.geocoder import database, lookup +from astral.sun import sun from datetime import datetime, timedelta try: @@ -75,54 +83,55 @@ def x_from_sun_moon_time(progress, period, x_range): return x -def sun_moon_time(dt, city_name, time_zone): +def sun_moon_time(city_name, time_zone): """Calculate the progress through the current sun/moon period (i.e day or night) from the last sunrise or sunset, given a datetime object 't'.""" - a = Astral() - city = a[city_name] + city = lookup(city_name, database()) # Datetime objects for yesterday, today, tomorrow - today = dt.date() - dt = pytz.timezone(time_zone).localize(dt) + utc = pytz.utc + utc_dt = datetime.now(tz=utc) + local_dt = utc_dt.astimezone(pytz.timezone(time_zone)) + today = local_dt.date() yesterday = today - timedelta(1) tomorrow = today + timedelta(1) - # Sun objects for yesterfay, today, tomorrow - sun_yesterday = city.sun(date=yesterday, local=True) - sun = city.sun(date=today, local=True) - sun_tomorrow = city.sun(date=tomorrow, local=True) + # Sun objects for yesterday, today, tomorrow + sun_yesterday = sun(city.observer, date=yesterday) + sun_today = sun(city.observer, date=today) + sun_tomorrow = sun(city.observer, date=tomorrow) # Work out sunset yesterday, sunrise/sunset today, and sunrise tomorrow sunset_yesterday = sun_yesterday["sunset"] - sunrise_today = sun["sunrise"] - sunset_today = sun["sunset"] + sunrise_today = sun_today["sunrise"] + sunset_today = sun_today["sunset"] sunrise_tomorrow = sun_tomorrow["sunrise"] # Work out lengths of day or night period and progress through period - if sunrise_today < dt < sunset_today: + if sunrise_today < local_dt < sunset_today: day = True period = sunset_today - sunrise_today - mid = sunrise_today + (period / 2) - progress = dt - sunrise_today + # mid = sunrise_today + (period / 2) + progress = local_dt - sunrise_today - elif dt > sunset_today: + elif local_dt > sunset_today: day = False period = sunrise_tomorrow - sunset_today - mid = sunset_today + (period / 2) - progress = dt - sunset_today + # mid = sunset_today + (period / 2) + progress = local_dt - sunset_today else: day = False period = sunrise_today - sunset_yesterday - mid = sunset_yesterday + (period / 2) - progress = dt - sunset_yesterday + # mid = sunset_yesterday + (period / 2) + progress = local_dt - sunset_yesterday # Convert time deltas to seconds progress = progress.total_seconds() period = period.total_seconds() - return (progress, period, day) + return (progress, period, day, local_dt) def draw_background(progress, period, day): @@ -136,7 +145,7 @@ def draw_background(progress, period, day): if day: x = WIDTH - x - # Calculate position on sun/moon's curve + # Calculate position on sun/moon's curve centre = WIDTH / 2 y = calculate_y_pos(x, centre) @@ -145,7 +154,7 @@ def draw_background(progress, period, day): # New image for background colour img = Image.new('RGBA', (WIDTH, HEIGHT), color=background) - draw = ImageDraw.Draw(img) + # draw = ImageDraw.Draw(img) # New image for sun/moon overlay overlay = Image.new('RGBA', (WIDTH, HEIGHT), color=(0, 0, 0, 0)) @@ -210,12 +219,12 @@ def analyse_pressure(pressure, t): slope = line[0][0] intercept = line[0][1] variance = numpy.var(pressure_vals) - residuals = numpy.var([(slope * x + intercept - y) for x, y in zip(time_vals, pressure_vals)]) + residuals = numpy.var([(slope * x + intercept - y) for x, y in zip(time_vals, pressure_vals)]) r_squared = 1 - residuals / variance # Calculate change in pressure per hour change_per_hour = slope * 60 * 60 - variance_per_hour = variance * 60 * 60 + # variance_per_hour = variance * 60 * 60 mean_pressure = numpy.mean(pressure_vals) @@ -238,10 +247,10 @@ def analyse_pressure(pressure, t): change_per_hour = 0 trend = "-" -# time.sleep(interval) - + # time.sleep(interval) return (mean_pressure, change_per_hour, trend) + def describe_pressure(pressure): """Convert pressure into barometer-type description.""" if pressure < 970: @@ -316,14 +325,13 @@ font_lg = ImageFont.truetype(UserFont, 14) # Margins margin = 3 -dt = datetime.now() # Set up BME280 weather sensor bus = SMBus(1) bme280 = BME280(i2c_dev=bus) -min_temp = bme280.get_temperature() -max_temp = bme280.get_temperature() +min_temp = None +max_temp = None factor = 2.25 cpu_temps = [get_cpu_temperature()] * 5 @@ -338,15 +346,18 @@ num_vals = 1000 interval = 1 trend = "-" +# Keep track of time elapsed +start_time = time.time() + while True: - dt = datetime.now() -# dt += timedelta(minutes=5) - progress, period, day = sun_moon_time(dt, city_name, time_zone) + path = os.path.dirname(os.path.realpath(__file__)) + progress, period, day, local_dt = sun_moon_time(city_name, time_zone) background = draw_background(progress, period, day) # Time. - date_string = dt.strftime("%d %b %y").lstrip('0') - time_string = dt.strftime("%H:%M") + time_elapsed = time.time() - start_time + date_string = local_dt.strftime("%d %b %y").lstrip('0') + time_string = local_dt.strftime("%H:%M") img = overlay_text(background, (0 + margin, 0 + margin), time_string, font_lg) img = overlay_text(img, (WIDTH - margin, 0 + margin), date_string, font_lg, align_right=True) @@ -359,17 +370,25 @@ while True: avg_cpu_temp = sum(cpu_temps) / float(len(cpu_temps)) corr_temperature = temperature - ((avg_cpu_temp - temperature) / factor) - if corr_temperature < min_temp: - min_temp = corr_temperature - elif corr_temperature > max_temp: - max_temp = corr_temperature + if time_elapsed > 30: + if min_temp is not None and max_temp is not None: + if corr_temperature < min_temp: + min_temp = corr_temperature + elif corr_temperature > max_temp: + max_temp = corr_temperature + else: + min_temp = corr_temperature + max_temp = corr_temperature temp_string = f"{corr_temperature:.0f}°C" img = overlay_text(img, (68, 18), temp_string, font_lg, align_right=True) spacing = font_lg.getsize(temp_string)[1] + 1 - range_string = f"{min_temp:.0f}-{max_temp:.0f}" + if min_temp is not None and max_temp is not None: + range_string = f"{min_temp:.0f}-{max_temp:.0f}" + else: + range_string = "------" img = overlay_text(img, (68, 18 + spacing), range_string, font_sm, align_right=True, rectangle=True) - temp_icon = Image.open("icons/temperature.png") + temp_icon = Image.open(f"{path}/icons/temperature.png") img.paste(temp_icon, (margin, 18), mask=temp_icon) # Humidity @@ -380,7 +399,7 @@ while True: spacing = font_lg.getsize(humidity_string)[1] + 1 humidity_desc = describe_humidity(corr_humidity).upper() img = overlay_text(img, (68, 48 + spacing), humidity_desc, font_sm, align_right=True, rectangle=True) - humidity_icon = Image.open("icons/humidity-" + humidity_desc.lower() + ".png") + humidity_icon = Image.open(f"{path}/icons/humidity-{humidity_desc.lower()}.png") img.paste(humidity_icon, (margin, 48), mask=humidity_icon) # Light @@ -390,7 +409,7 @@ while True: spacing = font_lg.getsize(light_string.replace(",", ""))[1] + 1 light_desc = describe_light(light).upper() img = overlay_text(img, (WIDTH - margin - 1, 18 + spacing), light_desc, font_sm, align_right=True, rectangle=True) - light_icon = Image.open("icons/bulb-" + light_desc.lower() + ".png") + light_icon = Image.open(f"{path}/icons/bulb-{light_desc.lower()}.png") img.paste(humidity_icon, (80, 18), mask=light_icon) # Pressure @@ -402,7 +421,7 @@ while True: pressure_desc = describe_pressure(mean_pressure).upper() spacing = font_lg.getsize(pressure_string.replace(",", ""))[1] + 1 img = overlay_text(img, (WIDTH - margin - 1, 48 + spacing), pressure_desc, font_sm, align_right=True, rectangle=True) - pressure_icon = Image.open("icons/weather-" + pressure_desc.lower() + ".png") + pressure_icon = Image.open(f"{path}/icons/weather-{pressure_desc.lower()}.png") img.paste(pressure_icon, (80, 48), mask=pressure_icon) # Display image