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
|
2018-10-01 01:18:23 +02:00
|
|
|
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-08-27 00:21:30 +02:00
|
|
|
Copyright by Ace-Laboratory
|
|
|
|
"""
|
2018-11-25 22:58:32 +01:00
|
|
|
print('importing modules'+'\n')
|
2018-10-10 23:23:34 +02:00
|
|
|
from settings import *
|
2018-11-25 22:58:32 +01:00
|
|
|
from icon_positions_locations import *
|
2018-10-01 01:18:23 +02:00
|
|
|
|
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
|
|
|
|
from urllib.request import urlopen
|
|
|
|
import arrow
|
|
|
|
|
2018-10-01 01:18:23 +02:00
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
while True:
|
|
|
|
|
|
|
|
time = datetime.now()
|
|
|
|
hour = int(time.strftime("%-H"))
|
|
|
|
|
|
|
|
for i in range(1):
|
2018-11-25 22:58:32 +01:00
|
|
|
"""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):
|
|
|
|
print('performing calibration now')
|
2018-08-27 00:21:30 +02:00
|
|
|
calibration()
|
2018-11-25 22:58:32 +01:00
|
|
|
|
|
|
|
print('Current date:',time.strftime('%a %-d %b %y'))
|
|
|
|
print('Current time:', time.strftime('%H:%M')+'\n')
|
|
|
|
|
|
|
|
"""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
|
2018-11-25 22:58:32 +01:00
|
|
|
|
|
|
|
"""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'))
|
|
|
|
|
2018-11-25 22:58:32 +01:00
|
|
|
"""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)
|
2018-11-25 22:58:32 +01:00
|
|
|
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)
|
2018-11-25 22:58:32 +01:00
|
|
|
draw(weekdayssun[(time.strftime("%a"))], weekday)
|
2018-08-27 00:21:30 +02:00
|
|
|
|
2018-11-25 22:58:32 +01: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)
|
2018-11-25 22:58:32 +01:00
|
|
|
#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-11-25 22:58:32 +01:00
|
|
|
""" Handling Openweathermap API"""
|
2018-10-23 23:10:32 +02:00
|
|
|
try:
|
2018-11-25 22:58:32 +01:00
|
|
|
print("Preparing to fetch data from openweathermap API")
|
2018-10-23 23:10:32 +02:00
|
|
|
owm = pyowm.OWM(api_key)
|
|
|
|
observation = owm.weather_at_place(location)
|
|
|
|
print("Fetching weather data...")
|
|
|
|
weather = observation.get_weather()
|
|
|
|
weathericon = weather.get_weather_icon_name()
|
2018-11-25 22:58:32 +01:00
|
|
|
|
|
|
|
Temperature = str(int(weather.get_temperature(unit='celsius')['temp']))
|
|
|
|
Humidity = str(weather.get_humidity())
|
|
|
|
print('temperature: '+Temperature +' °C')
|
|
|
|
print('humidity: '+Humidity+'%')
|
|
|
|
print('fetched icon code: '+weathericon)
|
|
|
|
print('equivalent to icon: '+weathericons[weathericon]+'\n')
|
|
|
|
|
|
|
|
"""Drawing the fetched weather icon"""
|
|
|
|
draw(wiconplace, open(wpath+weathericons[weathericon]+'.bmp'))
|
|
|
|
|
|
|
|
"""Drawing the fetched temperature"""
|
|
|
|
space2 = Image.new('1', (50,35), color=255)
|
|
|
|
temperature = ImageDraw.Draw(space2)
|
|
|
|
temperature.text((2, 8), (Temperature + " °C"), fill=0 ,font=font)
|
|
|
|
rotate2 = space2.rotate(270, expand=1)
|
|
|
|
image.paste(rotate2, (605,334))
|
|
|
|
|
|
|
|
"""Drawing the fetched humidity"""
|
|
|
|
space3 = Image.new('1', (50,35), color=255)
|
|
|
|
humidity = ImageDraw.Draw(space3)
|
|
|
|
humidity.text((4, 8), (Humidity +'%'), fill=0 ,font=font)
|
|
|
|
rotate3 = space3.rotate(270, expand=1)
|
|
|
|
image.paste(rotate3, (570,334))
|
|
|
|
|
2018-10-23 23:10:32 +02:00
|
|
|
except Exception as e:
|
|
|
|
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
|
|
|
|
message = template.format(type(ex).__name__, ex.args)
|
|
|
|
print(message)
|
|
|
|
print("************ OWM DID NOT RESPOND *************")
|
2018-11-25 22:58:32 +01:00
|
|
|
print("Drawing the 'no-response' icon on the display now")
|
|
|
|
draw(wiconplace, no_response)
|
2018-10-23 23:10:32 +02:00
|
|
|
pass
|
2018-08-27 00:21:30 +02:00
|
|
|
|
2018-11-25 22:58:32 +01:00
|
|
|
"""Drawing today's date at the top left corner"""
|
2018-08-27 00:21:30 +02:00
|
|
|
space1=Image.new('1', (115,25), color=255)
|
|
|
|
date = ImageDraw.Draw(space1)
|
|
|
|
date.text((2, 3), (time.strftime('%a %-d %b %y')), font=font, fill=0)
|
|
|
|
rotate1 = space1.rotate(270, expand=1)
|
|
|
|
image.paste(rotate1, (595,20))
|
|
|
|
|
2018-11-25 22:58:32 +01:00
|
|
|
"""Sort the Events in your iCalendar"""
|
|
|
|
print('Fetching upcoming events from your calendar')
|
2018-08-27 00:21:30 +02:00
|
|
|
elist = []
|
|
|
|
for events in c.events:
|
2018-11-25 22:58:32 +01:00
|
|
|
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-11-25 22:58:32 +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-11-25 22:58:32 +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
|
|
|
|
|
2018-11-25 22:58:32 +01:00
|
|
|
|
|
|
|
"""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
|
|
|
|
|
|
|
|
draw(tempplace, tempicon)
|
|
|
|
draw(humplace, humicon)
|
2018-11-25 22:58:32 +01:00
|
|
|
|
|
|
|
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-11-25 22:58:32 +01:00
|
|
|
print('data sent successfully'+'\n')
|
|
|
|
print('letting the display sleep until the next hour')
|
2018-10-01 01:18:23 +02:00
|
|
|
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()
|