E-Paper-Calendar/Calendar/stable.py

243 lines
10 KiB
Python
Raw Normal View History

2018-10-10 23:23:34 +02:00
#!/usr/bin/python3
2018-10-03 19:01:10 +02:00
# -*- coding: utf-8 -*-
2018-08-27 00:21:30 +02:00
"""
2018-10-16 21:10:56 +02:00
E-Paper Software (main script) for the 3-colour and 2-Colour E-Paper display
A full and detailed breakdown for this code can be found in the wiki.
If you have any questions, feel free to open an issue at Github.
2018-12-24 21:14:27 +01:00
Copyright by aceisace
2018-08-27 00:21:30 +02:00
"""
2018-12-24 21:13:58 +01:00
print('importing modules')
2018-10-10 23:23:34 +02:00
from settings import *
from icon_positions_locations import *
2018-10-16 21:10:56 +02:00
from PIL import Image, ImageDraw, ImageFont, ImageOps
import calendar, pyowm
from ics import Calendar, Event
from datetime import datetime
from time import sleep
2018-12-24 21:13:58 +01:00
try:
from urllib.request import urlopen
except Exception as e:
print('It seems the network is offline :(')
pass
2018-10-16 21:10:56 +02:00
import arrow
2018-12-24 21:13:58 +01:00
print('modules imported successfully!'+'\n')
2018-10-16 21:10:56 +02:00
if display_colours == "bwr":
import epd7in5b
epd = epd7in5b.EPD()
from calibration import calibration
2018-08-27 00:21:30 +02:00
2018-10-16 21:10:56 +02:00
if display_colours == "bw":
import epd7in5
epd = epd7in5.EPD()
from calibration_bw import calibration
2018-08-27 00:21:30 +02:00
2018-08-27 14:28:54 +02:00
c = Calendar(urlopen(url).read().decode('UTF-8'))
2018-08-27 00:21:30 +02:00
e = Event()
EPD_WIDTH = 640
EPD_HEIGHT = 384
2018-12-24 21:13:58 +01:00
font = ImageFont.truetype(path+'Assistant-Bold.ttf', 18)
2018-08-27 00:21:30 +02:00
def main():
while True:
2018-12-24 21:13:58 +01:00
2018-08-27 00:21:30 +02:00
time = datetime.now()
hour = int(time.strftime("%-H"))
2018-12-24 21:13:58 +01:00
2018-08-27 00:21:30 +02:00
for i in range(1):
"""At the following hours (midnight, midday and 6 pm), perform
a calibration of the display's colours"""
if (hour is 0) or (hour is 12) or (hour is 18):
2018-12-24 21:13:58 +01:00
print('performing calibration for colours now')
2018-08-27 00:21:30 +02:00
calibration()
print('Current date:',time.strftime('%a %-d %b %y'))
print('Current time:', time.strftime('%H:%M')+'\n')
2018-12-24 21:13:58 +01:00
"""Create a blank page"""
2018-08-27 00:21:30 +02:00
image = Image.new('L', (EPD_WIDTH, EPD_HEIGHT), 255)
draw = (ImageDraw.Draw(image)).bitmap
"""Draw the icon showing the current month"""
2018-08-27 00:21:30 +02:00
draw(monthplace, Image.open(mpath+str(time.strftime("%B"))+'.bmp'))
"""Draw the 3 lines that seperates the top section"""
draw(seperatorplace, seperator)
"""Draw the icons with the weekday-names (Mon, Tue...) and
draw a circle on the current weekday"""
if (week_starts_on == "Monday"):
calendar.setfirstweekday(calendar.MONDAY)
2018-08-27 00:21:30 +02:00
draw(weekplace, weekmon)
draw(weekdaysmon[(time.strftime("%a"))], weekday)
if (week_starts_on == "Sunday"):
calendar.setfirstweekday(calendar.SUNDAY)
2018-08-27 00:21:30 +02:00
draw(weekplace, weeksun)
draw(weekdayssun[(time.strftime("%a"))], weekday)
2018-08-27 00:21:30 +02:00
"""Using the built-in calendar function, draw icons for each
number of the month (1,2,3,...28,29,30)"""
2018-08-27 00:21:30 +02:00
cal = calendar.monthcalendar(time.year, time.month)
#print(cal) #-uncomment for debugging with incorrect dates
2018-08-27 00:21:30 +02:00
for i in cal[0]:
draw(positions['a'+str(cal[0].index(i)+1)] ,open(dpath+str(i)+'.bmp'))
for i in cal[1]:
draw(positions['b'+str(cal[1].index(i)+1)] ,open(dpath+str(i)+'.bmp'))
for i in cal[2]:
draw(positions['c'+str(cal[2].index(i)+1)] ,open(dpath+str(i)+'.bmp'))
for i in cal[3]:
draw(positions['d'+str(cal[3].index(i)+1)] ,open(dpath+str(i)+'.bmp'))
for i in cal[4]:
draw(positions['e'+str(cal[4].index(i)+1)] ,open(dpath+str(i)+'.bmp'))
try:
for i in cal[5]:
draw(positions['f'+str(cal[5].index(i)+1)] ,Image.open(dpath+str(i)+'.bmp'))
except IndexError:
pass
2018-12-24 21:13:58 +01:00
def write_text(a,b, text, c,d):#a,b box-size #c,d box position
w, h = font.getsize(text)
if (w, h) > (a, b):
raise ValueError('Sorry, your text is too big for the box')
else:
x = int((a / 2) - (w / 2))
y = int((b / 2) - (h / 2))
space = Image.new('1', (a,b), color=255)
ImageDraw.Draw(space).text((x, y), text, fill=0 ,font=font)
image.paste(space.rotate(270, expand=1), (c,d))
""" Handling Openweathermap API"""
2018-12-24 21:13:58 +01:00
owm = pyowm.OWM(api_key)
if owm.is_API_online() is True: #test server connection
print("Preparing to fetch data from openweathermap API")
2018-10-23 23:10:32 +02:00
observation = owm.weather_at_place(location)
print("Fetching weather data...")
weather = observation.get_weather()
weathericon = weather.get_weather_icon_name()
2018-12-24 21:13:58 +01:00
Temperature = str(int(weather.get_temperature(unit='celsius')['temp']))
Humidity = str(weather.get_humidity())
2018-12-24 21:13:58 +01:00
print('temperature: '+Temperature +' °C')
print('humidity: '+Humidity+'%')
print('fetched icon code: '+weathericon)
print('equivalent to icon: '+weathericons[weathericon]+'\n')
2018-12-24 21:13:58 +01:00
windspeed= str(int(weather.get_wind()['speed']))
sunrisetime = str(datetime.fromtimestamp(int(weather.get_sunrise_time(timeformat='unix'))).strftime('%H:%M'))
sunsettime = str(datetime.fromtimestamp(int(weather.get_sunset_time(timeformat='unix'))).strftime('%H:%M'))
cloudstatus = str(weather.get_clouds())
weather_description = (str(weather.get_status()))
print('Current wind speed: '+windspeed+ 'km/h')
print('The sunrise today took take place place at: '+sunrisetime)
print('The sunset today will take place place at: '+sunsettime)
print('The current Cloud condition is: ' + cloudstatus + '%')
print('Weather: '+ weather_description)
"""Drawing the fetched weather icon"""
2018-12-24 21:13:58 +01:00
draw(wiconplace, open(wpath+weathericons[weathericon] + '.bmp'))
"""Drawing the fetched temperature"""
2018-12-24 21:13:58 +01:00
draw(tempplace, tempicon)
2018-12-24 22:33:08 +01:00
write_text(50,35, Temperature + " °C", 605, 334)
"""Drawing the fetched humidity"""
2018-12-24 21:13:58 +01:00
draw(humplace, humicon)
write_text(50,35, Humidity + " %", 570, 334)
"""Drawing the fetched sunrise time"""
draw(sunriseplace, sunriseicon)
write_text(50,35, sunrisetime, 605, 250)
"""Drawing the fetched sunset time"""
draw(sunsetplace, sunseticon)
write_text(50,35, sunsettime, 570, 250)
"""Drawing the fetched wind speed"""
draw(windiconspace, windicon)
write_text(75, 35, windspeed+" km/h", 605,135)
"""Write a short weather description"""
write_text(100,35, weather_description, 570, 100)
else:
draw(wiconplace, no_response)
2018-10-23 23:10:32 +02:00
pass
2018-08-27 00:21:30 +02:00
"""Sort the Events in your iCalendar"""
print('Fetching upcoming events from your calendar')
2018-08-27 00:21:30 +02:00
elist = []
2018-12-24 21:13:58 +01:00
eventstoday = []
2018-08-27 00:21:30 +02:00
for events in c.events:
if time.year <= int((events.begin).format('YYYY')):
if time.month == int((events.begin).format('M')):
2018-08-27 00:21:30 +02:00
elist.append(int((events.begin).format('D')))
2018-12-24 21:13:58 +01:00
"""Uncomment the next 4 lines to print your events on the console"""
# if time.day <= int((events.begin).format('D')):
# print(events.name+' starts on '+events.begin.format('D '+'MMM '+'YYYY'))
# if time.month < int((events.begin).format('M')):
# print(events.name+' starts on '+events.begin.format('D '+'MMM '+'YYYY'))
2018-08-27 00:21:30 +02:00
2018-12-24 21:13:58 +01:00
"""Draw circles on any days which include an Event"""
2018-08-27 00:21:30 +02:00
for x in elist:
if x in cal[0]:
draw(positions['a'+str(cal[0].index(x)+1)] ,eventicon)
if x in cal[1]:
draw(positions['b'+str(cal[1].index(x)+1)] ,eventicon)
if x in cal[2]:
draw(positions['c'+str(cal[2].index(x)+1)] ,eventicon)
if x in cal[3]:
draw(positions['d'+str(cal[3].index(x)+1)] ,eventicon)
if x in cal[4]:
draw(positions['e'+str(cal[4].index(x)+1)] ,eventicon)
try:
if x in cal[5]:
draw(positions['f'+str(cal[5].index(x)+1)] ,eventicon)
except IndexError:
pass
"""Draw a square with round corners on the today's date"""
2018-08-27 00:21:30 +02:00
today = time.day
if today in cal[0]:
draw(positions['a'+str(cal[0].index(today)+1)] ,dateicon)
if today in cal[1]:
draw(positions['b'+str(cal[1].index(today)+1)] ,dateicon)
if today in cal[2]:
draw(positions['c'+str(cal[2].index(today)+1)] ,dateicon)
if today in cal[3]:
draw(positions['d'+str(cal[3].index(today)+1)] ,dateicon)
if today in cal[4]:
draw(positions['e'+str(cal[4].index(today)+1)] ,dateicon)
try:
if today in cal[5]:
draw(positions['f'+str(cal[5].index(today)+1)] ,dateicon)
except IndexError:
pass
print('\n'+'initialising E-Paper Display')
epd.init()
sleep(5)
print('Converting image to data and sending it to the display...'+'\n')
2018-08-27 00:21:30 +02:00
epd.display_frame(epd.get_frame_buffer(image))
# delete the list so deleted events can be removed from the list
del elist[:]
2018-12-24 21:13:58 +01:00
del eventstoday[:]
print('data sent successfully'+'\n')
print('letting the display sleep until the next hour')
epd.sleep()
2018-08-27 00:21:30 +02:00
for i in range(1):
nexthour = ((60 - int(time.strftime("%-M")))*60) - (int(time.strftime("%-S")))
sleep(nexthour)
if __name__ == '__main__':
main()