Skip to content

Instantly share code, notes, and snippets.

@wiomoc
Created October 18, 2022 20:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wiomoc/547f822151497713b7e0f8ac15e43ffd to your computer and use it in GitHub Desktop.
Save wiomoc/547f822151497713b7e0f8ac15e43ffd to your computer and use it in GitHub Desktop.
Daily printout
# 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