+#!/usr/bin/env python3
+
+import os
import time
import numpy
import colorsys
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:
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):
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)
# 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))
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)
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:
# 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
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)
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
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
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
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