Created
October 18, 2022 20:51
-
-
Save wiomoc/547f822151497713b7e0f8ac15e43ffd to your computer and use it in GitHub Desktop.
Daily printout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# requires https://github.com/erikflowers/weather-icons/blob/master/font/weathericons-regular-webfont.ttf saved as weathericons.ttf along the project | |
import datetime | |
import json | |
import urllib.request | |
from collections import defaultdict | |
from PIL import ImageDraw, Image, ImageFont | |
# Weather | |
def mode(arr): | |
m = defaultdict(int) | |
for i in arr: | |
m[i] += 1 | |
return max(m.items(), key=lambda a: a[1])[0] | |
ICON_MAPPING = { | |
'clear': "\uf00d", | |
'clear-day': "\uf00d", | |
'clear-night': "\uf02e", | |
'partly-cloudy': "\uf002", | |
'partly-cloudy-day': "\uf002", | |
'partly-cloudy-night': "\uf031", | |
'cloudy': "\uf031", | |
'fog': "\uf014", | |
'wind': "\uf050", | |
'rain': "\uf019", | |
'sleet': "\uf0b5", | |
'snow': "\uf01b", | |
'hail': "\uf015", | |
'thunderstorm': "\uf01e", | |
'umbrella': "\uf084", | |
'sunny-day': "\uf00d", | |
'barometer': "\uf079" | |
} | |
def get_weather(coord=(50.12, 8.76), date=datetime.date.today()): | |
data = json.load(urllib.request.urlopen( | |
url=f"https://api.brightsky.dev/weather?lat={coord[0]}&lon={coord[1]}&date={date.isoformat()}")) | |
weather_data = data['weather'] | |
def extract(dimension): | |
return (point[dimension] for point in weather_data) | |
min_temp = min(extract('temperature')) | |
max_temp = max(extract('temperature')) | |
day_icon = mode((icon.replace("-day", "").replace("-night", "") for icon in extract('icon'))) | |
total_rain = sum(extract('precipitation')) | |
total_sunshine = sum(extract('sunshine')) | |
avg_cloud_cover = sum(extract('cloud_cover')) / len(weather_data) | |
wind_speed = sum(extract('wind_speed')) / len(weather_data) | |
avg_pressure = sum(extract('pressure_msl')) / len(weather_data) | |
print(min_temp, max_temp, day_icon, total_rain, total_sunshine, avg_cloud_cover, wind_speed) | |
image = Image.new("1", (512, 270), "white") | |
draw = ImageDraw.Draw(image) | |
arial = ImageFont.truetype("arial.ttf", 35) | |
arial_bold = ImageFont.truetype("arial_bold.ttf",35) | |
weather_icons = ImageFont.truetype("weathericons.ttf", 90) | |
draw.text((20, 5), "%.1f °C" % max_temp, font=arial_bold) | |
draw.text((120, 5.5), " · %.1f °C" % min_temp, font=arial) | |
draw.text((380, 10), ICON_MAPPING[day_icon], font=weather_icons) | |
weather_icons_30 = weather_icons.font_variant(size=30) | |
draw.text((20, 45), ICON_MAPPING['sunny-day'], font=weather_icons_30) | |
draw.text((60, 45), "%u:%02u h" % (int(total_sunshine / 60), int(total_sunshine % 60)), font=arial) | |
draw.text((20, 80), ICON_MAPPING['wind'], font=weather_icons_30) | |
draw.text((60, 80), "%.01f km/h" % wind_speed, font=arial) | |
draw.text((25, 115), ICON_MAPPING['barometer'], font=weather_icons_30) | |
draw.text((60, 115), "%.00f hPa" % avg_pressure, font=arial) | |
draw.text((230, 80), ICON_MAPPING['rain'], font=weather_icons_30) | |
draw.text((270, 80), "%.01f l" % total_rain, font=arial) | |
draw.text((230, 115), ICON_MAPPING['cloudy'], font=weather_icons_30) | |
draw.text((270, 115), "%u%%" % avg_cloud_cover, font=arial) | |
weather_icons_35 = weather_icons.font_variant(size=35) | |
arial_small = arial.font_variant(size=30) | |
start = 3 | |
for i in range(start, 24, 4): | |
time_str = "%02u:00" % (i + 1) | |
icon = weather_data[i]['icon'] | |
temp = weather_data[i]['temperature'] | |
offset = 25 * (i - start) | |
draw.text((15 + offset, 160), time_str, font=arial_small) | |
draw.text((32 + offset, 190), ICON_MAPPING[icon], font=weather_icons_35) | |
draw.text((10 + offset, 235), "%.00f °C" % temp, font=arial) | |
return image | |
# todoist | |
from todoist_api_python.api import TodoistAPI | |
def get_todo_items(): | |
api = TodoistAPI("<myapikey>") # | |
try: | |
tasks = api.get_tasks(filter="today|overdue") | |
return "\n".join(("() " + task.content for task in tasks)) | |
except Exception as error: | |
return "Could not load todolist" | |
#appointments | |
import datetime | |
import caldav.davclient | |
from requests.auth import HTTPBasicAuth | |
def get_appointments(): | |
try: | |
calendar = caldav.davclient.DAVClient("https://p56-caldav.icloud.com/<path>", | |
auth=HTTPBasicAuth("<username>", "<password>")).calendar( | |
url="home") | |
today = datetime.date.today() | |
events = calendar.date_search(start=datetime.datetime.combine(today, datetime.time()), | |
end=datetime.datetime.combine(today, datetime.time(23, 59, 29))) | |
appointments = [] | |
for event in events: | |
event.load() | |
vevent = event.instance.vevent | |
appointments.append(f"{vevent.dtstart.value.strftime('%H:%M')} - {vevent.dtend.value.strftime('%H:%M')}: {vevent.summary.value}") | |
return "\n".join(appointments) | |
except: | |
return "Failed to get appointments" | |
# news headlines | |
import feedparser | |
def get_news(): | |
try: | |
feed = feedparser.parse("https://www.tagesschau.de/newsticker.rdf").entries[:6] | |
return "\n".join(["- " + entry["title"] for entry in feed]) | |
except: | |
return "Could not load news" | |
#facts | |
import json | |
import urllib.request | |
def get_fact(): | |
try: | |
request = urllib.request.Request("https://api.api-ninjas.com/v1/facts?limit=1") | |
request.add_header("X-Api-Key", "<token>") | |
return json.load(urllib.request.urlopen(request))[0]["fact"] | |
except: | |
return "Could not load fact" | |
p = printer.Serial(devfile="/dev/ttyUSB0", baudrate=38400) | |
p.set(double_height=True, bold=True, align="center") | |
p.text(datetime.date.today().strftime("%A, the %d. %B(%m) %Y\n")) | |
p.set(double_height=False, bold=False, align="left") | |
try: | |
p.image(get_weather()) | |
except Exception as e: | |
print(e) | |
p.text("Could not get weather\n") | |
p.set(double_height=True) | |
p.text("Todos\n") | |
p.set(double_height=False) | |
p.text(get_todo_items()) | |
p.text("\n") | |
p.set(double_height=True) | |
p.text("Appointments\n") | |
p.set(double_height=False) | |
p.text(get_appointments()) | |
p.text("\n") | |
p.set(double_height=True) | |
p.text("News\n") | |
p.set(double_height=False) | |
p.text(get_news()) | |
p.text("\n\n") | |
p.text(get_fact()) | |
p.cut() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment