diff --git a/Calendar/Assistant-Regular.ttf b/Calendar/Assistant-Regular.ttf deleted file mode 100644 index f557311..0000000 Binary files a/Calendar/Assistant-Regular.ttf and /dev/null differ diff --git a/Calendar/E-Paper.py b/Calendar/E-Paper.py index 2b95c0e..74467eb 100644 --- a/Calendar/E-Paper.py +++ b/Calendar/E-Paper.py @@ -13,24 +13,15 @@ from datetime import datetime, date, timedelta from time import sleep from dateutil.rrule import * from dateutil.parser import parse +import arrow import re import random import gc - -try: - import feedparser -except ImportError: - print("Please install feedparser with: sudo pip3 install feedparser") - print("and") - print("pip3 install feedparser") - -try: - import numpy as np -except ImportError: - print("Please install numpy with: sudo apt-get install python3-numpy") +import feedparser +import numpy as np from settings import * -from icon_positions_locations import * +from image_data import * from PIL import Image, ImageDraw, ImageFont, ImageOps import pyowm @@ -40,29 +31,23 @@ try: except Exception as e: print("Something didn't work right, maybe you're offline?"+e.reason) -if display_colours is "bwr": - import epd7in5b - epd = epd7in5b.EPD() - -if display_colours is "bw": - import epd7in5 - epd = epd7in5.EPD() +import e_paper_drivers +epd = e_paper_drivers.EPD() from calibration import calibration EPD_WIDTH = 640 EPD_HEIGHT = 384 -font = ImageFont.truetype(path+'Assistant-Regular.ttf', 18) + +default = ImageFont.truetype(fpath+'NotoSans/NotoSans-SemiCondensedLight.ttf', 18) +semi = ImageFont.truetype(fpath+'NotoSans/NotoSans-SemiCondensed.ttf', 18) +bold = ImageFont.truetype(fpath+'NotoSans/NotoSans-SemiCondensedMedium.ttf', 18) +month_font = ImageFont.truetype(fpath+'NotoSans/NotoSans-SemiCondensedLight.ttf', 40) + im_open = Image.open owm = pyowm.OWM(api_key) -possible_update_values = [10, 15, 20, 30, 60] -if int(update_interval) not in possible_update_values: - print('Selected update-interval: ',update_interval, 'minutes') - print('Please select an update interval from these values:', possible_update_values) - raise ValueError - """Main loop starts from here""" def main(): calibration_countdown = 'initial' @@ -73,6 +58,7 @@ def main(): year = int(time.now().strftime('%Y')) mins = int(time.strftime("%M")) seconds = int(time.strftime("%S")) + now = arrow.now() for i in range(1): print('_________Starting new loop___________'+'\n') @@ -94,213 +80,174 @@ def main(): """Create a blank white page first""" image = Image.new('RGB', (EPD_HEIGHT, EPD_WIDTH), 'white') - """Add the icon with the current month's name""" - image.paste(im_open(mpath+str(time.strftime("%B")+'.jpeg')), monthplace) - - """Add the line seperating the weather and Calendar section""" - image.paste(seperator, seperatorplace) - - """Add weekday-icons (Mon, Tue...) and draw a circle on the - current weekday""" - if (week_starts_on is "Monday"): - calendar.setfirstweekday(calendar.MONDAY) - image.paste(weekmon, weekplace) - image.paste(weekday, weekdaysmon[(time.strftime("%a"))], weekday) - - """For those whose week starts on Sunday, change accordingly""" - if (week_starts_on is "Sunday"): - calendar.setfirstweekday(calendar.SUNDAY) - image.paste(weeksun, weekplace) - image.paste(weekday, weekdayssun[(time.strftime("%a"))], weekday) - - """Using the built-in calendar function, draw icons for each - number of the month (1,2,3,...28,29,30)""" - cal = calendar.monthcalendar(time.year, time.month) - - for numbers in cal[0]: - image.paste(im_open(dpath+str(numbers)+'.jpeg'), positions['a'+str(cal[0].index(numbers)+1)]) - for numbers in cal[1]: - image.paste(im_open(dpath+str(numbers)+'.jpeg'), positions['b'+str(cal[1].index(numbers)+1)]) - for numbers in cal[2]: - image.paste(im_open(dpath+str(numbers)+'.jpeg'), positions['c'+str(cal[2].index(numbers)+1)]) - for numbers in cal[3]: - image.paste(im_open(dpath+str(numbers)+'.jpeg'), positions['d'+str(cal[3].index(numbers)+1)]) - for numbers in cal[4]: - image.paste(im_open(dpath+str(numbers)+'.jpeg'), positions['e'+str(cal[4].index(numbers)+1)]) - if len(cal) is 6: - for numbers in cal[5]: - image.paste(im_open(dpath+str(numbers)+'.jpeg'), positions['f'+str(cal[5].index(numbers)+1)]) - - """Custom function to display text on the E-Paper. - Tuple refers to the x and y coordinates of the E-Paper display, - with (0, 0) being the top left corner of the display.""" - def write_text(box_width, box_height, text, tuple): - text_width, text_height = font.getsize(text) - if (text_width, text_height) > (box_width, box_height): - raise ValueError('Sorry, your text is too big for the box') - else: - x = int((box_width / 2) - (text_width / 2)) - y = int((box_height / 2) - (text_height / 2)) - space = Image.new('RGB', (box_width, box_height), color='white') - ImageDraw.Draw(space).text((x, y), text, fill='black', font=font) - image.paste(space, tuple) - - """Connect to Openweathermap API to fetch weather data""" - print("Connecting to Openweathermap API servers...") - if owm.is_API_online() is True: - observation = owm.weather_at_place(location) - print("weather data:") - weather = observation.get_weather() - weathericon = weather.get_weather_icon_name() - Humidity = str(weather.get_humidity()) - cloudstatus = str(weather.get_clouds()) - weather_description = (str(weather.get_status())) - - if units is "metric": - Temperature = str(int(weather.get_temperature(unit='celsius')['temp'])) - windspeed = str(int(weather.get_wind()['speed'])) - write_text(50, 35, Temperature + " °C", (334, 0)) - write_text(100, 35, windspeed+" km/h", (114, 0)) - - if units is "imperial": - Temperature = str(int(weather.get_temperature('fahrenheit')['temp'])) - windspeed = str(int(weather.get_wind()['speed']*0.621)) - write_text(50, 35, Temperature + " °F", (334, 0)) - write_text(100, 35, windspeed+" mph", (114, 0)) - - if hours is "24": - 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')) - - if hours is "12": - sunrisetime = str(datetime.fromtimestamp(int(weather.get_sunrise_time(timeformat='unix'))).strftime('%-I:%M')) - sunsettime = str(datetime.fromtimestamp(int(weather.get_sunset_time(timeformat='unix'))).strftime('%-I:%M')) - - print('Temperature: '+Temperature+' °C') - print('Humidity: '+Humidity+'%') - #print('Icon code: '+weathericon) - print('weather-icon name: '+weathericons[weathericon]) - print('Wind speed: '+windspeed+'km/h') - print('Sunrise-time: '+sunrisetime) - print('Sunset time: '+sunsettime) - print('Cloudiness: ' + cloudstatus+'%') - print('Weather description: '+weather_description+'\n') - - """Add the weather icon at the top left corner""" - image.paste(im_open(wpath+weathericons[weathericon]+'.jpeg'), wiconplace) - - """Add the temperature icon at it's position""" - image.paste(tempicon, tempplace) - - """Add the humidity icon and display the humidity""" - image.paste(humicon, humplace) - write_text(50, 35, Humidity + " %", (334, 35)) - - """Add the sunrise icon and display the sunrise time""" - image.paste(sunriseicon, sunriseplace) - write_text(50, 35, sunrisetime, (249, 0)) - - """Add the sunset icon and display the sunrise time""" - image.paste(sunseticon, sunsetplace) - write_text(50, 35, sunsettime, (249, 35)) - - """Add the wind icon at it's position""" - image.paste(windicon, windiconspace) - - """Add a short weather description""" - write_text(144, 35, weather_description, (70, 35)) - - else: - """If no response was received from the openweathermap - api server, add the cloud with question mark""" - image.paste(no_response, wiconplace) - - """Algorithm for filtering and sorting events from your - iCalendar/s""" - print('Fetching events from your calendar'+'\n') - events_this_month = [] - upcoming = [] - today = date.today() - - """Create a time span using the events_max_range value (in days) - to filter events in that range""" - time_span = today + timedelta(days=int(events_max_range)) - - for icalendars in ical_urls: - decode = str(urlopen(icalendars).read().decode()) - beginAlarmIndex = 0 - while beginAlarmIndex >= 0: - beginAlarmIndex = decode.find('BEGIN:VALARM') - if beginAlarmIndex >= 0: - endAlarmIndex = decode.find('END:VALARM') - decode = decode[:beginAlarmIndex] + decode[endAlarmIndex+12:] - ical = Calendar(decode) - for events in ical.events: - if re.search('RRULE',str(events)) is not None: - r = re.search('RRULE:(.+?)\n',str(events)) - r_start = re.search('DTSTART:(.+?)\n',str(events)) - if r_start is not None: # if r_start is None the format of DTSTART is not recognized - if time.now().month == 12: - r_string=(r.group(1).rstrip()+';UNTIL='+'%04d%02d%02d'+'T000000Z') % (time.now().year+1, 1, 1) - else: - r_string=(r.group(1).rstrip()+';UNTIL='+'%04d%02d%02d'+'T000000Z') % (time.now().year, time.now().month+1, 1) - rule=rrulestr(r_string,dtstart=parse(r_start.group(1))) - for i in rule: - if i.year == time.now().year and i.month == time.now().month and i.day >= time.now().day: - upcoming.append({'date':str(time.now().year) + " " + time.now().strftime('%m')+ " " + str(i.day).zfill(2), 'event':events.name}) - if i.day not in events_this_month: - events_this_month.append(i.day) - # uncomment this line to see fetched recurring events - #print ("Appended recurring event: " + events.name + " on " + str(time.now().year) + " " + time.now().strftime('%m')+ " " + str(i.day).zfill(2)) - else: - if events.begin.date().month == today.month: - if int((events.begin).format('D')) not in events_this_month: - events_this_month.append(int((events.begin).format('D'))) - if today <= events.begin.date() <= time_span: - upcoming.append({'date':events.begin.format('YYYY MM DD'), 'event':events.name}) - - - def takeDate(elem): - return elem['date'] - - upcoming.sort(key=takeDate) - - #print('Upcoming events:',upcoming) #Display fetched events - - def write_text_left(box_width, box_height, text, tuple): + """Custom function to display text on the E-Paper""" + def write_text(box_width, box_height, text, tuple, font=default, alignment='middle'): text_width, text_height = font.getsize(text) while (text_width, text_height) > (box_width, box_height): text=text[0:-1] text_width, text_height = font.getsize(text) - y = int((box_height / 2) - (text_height / 2)) + if alignment is "" or "middle" or None: + x = int((box_width / 2) - (text_width / 2)) + if alignment is 'left': + x = 0 + y = int((box_height / 2) - (text_height / 1.7)) space = Image.new('RGB', (box_width, box_height), color='white') - ImageDraw.Draw(space).text((0, y), text, fill='black', font=font) + ImageDraw.Draw(space).text((x, y), text, fill='black', font=font) image.paste(space, tuple) - """Write event dates and names on the E-Paper""" - if additional_feature is "events": - if len(cal) is 5: - del upcoming[6:] + """Check if internet is available by trying to reach google""" + def internet_available(): + try: + urlopen('https://google.com',timeout=5) + return True + except URLError as err: + return False - for dates in range(len(upcoming)): - readable_date = datetime.strptime(upcoming[dates]['date'], '%Y %m %d').strftime('%-d %b') - write_text(70, 25, readable_date, date_positions['d'+str(dates+1)]) - for events in range(len(upcoming)): - write_text_left(314, 25, (upcoming[events]['event']), event_positions['e'+str(events+1)]) + """Connect to Openweathermap API and fetch weather data""" + if top_section is "Weather" and api_key != "" and owm.is_API_online() is True: + try: + print("Connecting to Openweathermap API servers...") + observation = owm.weather_at_place(location) + print("weather data:") + weather = observation.get_weather() + weathericon = weather.get_weather_icon_name() + Humidity = str(weather.get_humidity()) + cloudstatus = str(weather.get_clouds()) + weather_description = (str(weather.get_status())) + if units is "metric": + Temperature = str(int(weather.get_temperature(unit='celsius')['temp'])) + windspeed = str(int(weather.get_wind()['speed'])) + write_text(50, 35, Temperature + " °C", (334, 0)) + write_text(100, 35, windspeed+" km/h", (114, 0)) + + if units is "imperial": + Temperature = str(int(weather.get_temperature('fahrenheit')['temp'])) + windspeed = str(int(weather.get_wind()['speed']*0.621)) + write_text(50, 35, Temperature + " °F", (334, 0)) + write_text(100, 35, windspeed+" mph", (114, 0)) + + if hours is "24": + 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')) + + if hours is "12": + sunrisetime = str(datetime.fromtimestamp(int(weather.get_sunrise_time(timeformat='unix'))).strftime('%-I:%M')) + sunsettime = str(datetime.fromtimestamp(int(weather.get_sunset_time(timeformat='unix'))).strftime('%-I:%M')) + + """Show the fetched weather data""" + print('Temperature: '+ Temperature+' °C') + print('Humidity: '+ Humidity+'%') + print('weather-icon name: '+weathericons[weathericon]) + print('Wind speed: '+ windspeed+'km/h') + print('Sunrise-time: '+ sunrisetime) + print('Sunset time: '+ sunsettime) + print('Cloudiness: ' + cloudstatus+'%') + print('Weather description: '+ weather_description+'\n') + + """Add the weather icon at the top left corner""" + image.paste(im_open(wpath + weathericons[weathericon] +'.jpeg'), wiconplace) + + """Add the temperature icon at it's position""" + image.paste(tempicon, tempplace) + + """Add the humidity icon and display the humidity""" + image.paste(humicon, humplace) + write_text(50, 35, Humidity + " %", (334, 35)) + + """Add the sunrise icon and display the sunrise time""" + image.paste(sunriseicon, sunriseplace) + write_text(50, 35, sunrisetime, (249, 0)) + + """Add the sunset icon and display the sunrise time""" + image.paste(sunseticon, sunsetplace) + write_text(50, 35, sunsettime, (249, 35)) + + """Add the wind icon at it's position""" + image.paste(windicon, windiconspace) + + """Add a short weather description""" + write_text(144, 35, weather_description, (70, 35)) + + except Exception as e: + """If no response was received from the openweathermap + api server, add the cloud with question mark""" + print('__________OWM-ERROR!__________'+'\n') + print('Reason: ',e+'\n') + image.paste(no_response, wiconplace) + pass + + """Set the Calendar to start on the day specified by the settings file """ + if week_starts_on is "Monday": + calendar.setfirstweekday(calendar.MONDAY) + + """For those whose week starts on Sunday, change accordingly""" + if week_starts_on is "Sunday": + calendar.setfirstweekday(calendar.SUNDAY) + + """Using the built-in calendar to generate the monthly Calendar + template""" + cal = calendar.monthcalendar(time.year, time.month) + + if middle_section is "Calendar": + """Add the icon with the current month's name""" + write_text(384,60, now.format('MMMM',locale=language), monthplace, font=month_font) + + """Add the line seperating the weather and Calendar section""" + image.paste(seperator, seperatorplace) + + """Create a list containing the weekday abbrevations for the + chosen language""" + if week_starts_on is "Monday": + prev_weekstart = now.replace(days = - now.weekday()) + image.paste(weekday, weekday_pos['pos'+str(now.weekday())], weekday) + if week_starts_on is "Sunday": + prev_weekstart = now.replace(days = - now.isoweekday()) + image.paste(weekday, weekday_pos['pos'+str(now.isoweekday())], weekday) + + weekday_names_list = [] + for i in range(7): + weekday_name = prev_weekstart.replace(days=+i) + weekday_names_list.append(weekday_name.format('ddd',locale=language)) + + for i in range(len(weekday_names_list)): + write_text(54, 28, weekday_names_list[i], weekday_pos['pos'+str(i)]) + + """Create the calendar template of the current month""" + for numbers in cal[0]: + image.paste(im_open(dpath+str(numbers)+'.jpeg'), positions['a'+str(cal[0].index(numbers)+1)]) + for numbers in cal[1]: + image.paste(im_open(dpath+str(numbers)+'.jpeg'), positions['b'+str(cal[1].index(numbers)+1)]) + for numbers in cal[2]: + image.paste(im_open(dpath+str(numbers)+'.jpeg'), positions['c'+str(cal[2].index(numbers)+1)]) + for numbers in cal[3]: + image.paste(im_open(dpath+str(numbers)+'.jpeg'), positions['d'+str(cal[3].index(numbers)+1)]) + for numbers in cal[4]: + image.paste(im_open(dpath+str(numbers)+'.jpeg'), positions['e'+str(cal[4].index(numbers)+1)]) if len(cal) is 6: - del upcoming[4:] + for numbers in cal[5]: + image.paste(im_open(dpath+str(numbers)+'.jpeg'), positions['f'+str(cal[5].index(numbers)+1)]) - for dates in range(len(upcoming)): - readable_date = datetime.strptime(upcoming[dates]['date'], '%Y %m %d').strftime('%-d %b') - write_text(70, 25, readable_date, date_positions['d'+str(dates+3)]) - for events in range(len(upcoming)): - write_text_left(314, 25, (upcoming[events]['event']), event_positions['e'+str(events+3)]) + """Draw a larger square on today's date""" + today = time.day + if today in cal[0]: + image.paste(dateicon, positions['a'+str(cal[0].index(today)+1)], dateicon) + if today in cal[1]: + image.paste(dateicon, positions['b'+str(cal[1].index(today)+1)], dateicon) + if today in cal[2]: + image.paste(dateicon, positions['c'+str(cal[2].index(today)+1)], dateicon) + if today in cal[3]: + image.paste(dateicon, positions['d'+str(cal[3].index(today)+1)], dateicon) + if today in cal[4]: + image.paste(dateicon, positions['e'+str(cal[4].index(today)+1)], dateicon) + if len(cal) is 6 and today in cal[5]: + image.paste(dateicon, positions['f'+str(cal[5].index(today)+1)], dateicon) """Add rss-feeds at the bottom section of the Calendar""" - if additional_feature is "rss": + if bottom_section is "RSS" and rss_feeds != []: - def multiline_text(text, max_width): + """Custom function to display longer text into multiple lines (wrapping)""" + def multiline_text(text, max_width, font=default): lines = [] if font.getsize(text)[0] <= max_width: lines.append(text) @@ -318,69 +265,154 @@ def main(): lines.append(line) return lines + """Parse the RSS-feed titles and save them to a list""" rss_feed = [] for feeds in rss_feeds: text = feedparser.parse(feeds) for posts in text.entries: - rss_feed.append(posts.title) + rss_feed.append(posts.summary)#title + """Shuffle the list to prevent displaying the same titles over and over""" random.shuffle(rss_feed) news = [] - if len(cal) is 5: + """Remove all titles except the first 4 or 6, + depenfing on how much space is available on the """ + if middle_section is 'Calendar' and len(cal) is 5 or middle_section is 'Agenda': del rss_feed[6:] if len(cal) is 6: del rss_feed[4:] + """Split titles of the rss feeds into lines that can fit + on the Calendar and add them to a list""" for title in range(len(rss_feeds)): news.append(multiline_text(rss_feed[title], 384)) news = [j for i in news for j in i] - if len(cal) is 5: + """Display the split lines of the titles""" + if middle_section is 'Calendar' and len(cal) is 5 or middle_section is 'Agenda': if len(news) > 6: del news[6:] for lines in range(len(news)): - write_text_left(384, 25, news[lines], rss_places['line_'+str(lines+1)]) + write_text(384, 25, news[lines], rss_places['line_'+str(lines+1)], alignment = 'left') if len(cal) is 6: if len(news) > 4: del news[4:] for lines in range(len(news)): - write_text_left(384, 25, news[lines], rss_places['line_'+str(lines+3)]) + write_text(384, 25, news[lines], rss_places['line_'+str(lines+3)], alignment = 'left') - """Draw smaller squares on days with events""" - for numbers in events_this_month: - if numbers in cal[0]: - image.paste(eventicon, positions['a'+str(cal[0].index(numbers)+1)], eventicon) - if numbers in cal[1]: - image.paste(eventicon, positions['b'+str(cal[1].index(numbers)+1)], eventicon) - if numbers in cal[2]: - image.paste(eventicon, positions['c'+str(cal[2].index(numbers)+1)], eventicon) - if numbers in cal[3]: - image.paste(eventicon, positions['d'+str(cal[3].index(numbers)+1)], eventicon) - if numbers in cal[4]: - image.paste(eventicon, positions['e'+str(cal[4].index(numbers)+1)], eventicon) - if len(cal) is 6: - if numbers in cal[5]: + + if middle_section is "Calendar" or "Agenda": + """Algorithm for filtering and sorting events from your + iCalendar/s""" + events_this_month = [] + upcoming = [] + today = time.today() + + """Create a time span using the events_max_range value (in days) + to filter events in that range""" + agenda_max_days = arrow.now().replace(days=+22) + calendar_max_days = arrow.now().replace(days=+int(events_max_range)) + if internet_available() is True: + print('Internet connection test passed'+'\n') + print('Fetching events from your calendar'+'\n') + for icalendars in ical_urls: + decode = str(urlopen(icalendars).read().decode()) + beginAlarmIndex = 0 + while beginAlarmIndex >= 0: + beginAlarmIndex = decode.find('BEGIN:VALARM') + if beginAlarmIndex >= 0: + endAlarmIndex = decode.find('END:VALARM') + decode = decode[:beginAlarmIndex] + decode[endAlarmIndex+12:] + ical = Calendar(decode) + for events in ical.events: + if events.begin.date().year == today.year and events.begin.date().month is today.month: + if int((events.begin).format('D')) not in events_this_month: + events_this_month.append(int((events.begin).format('D'))) + if middle_section is 'Agenda' and events in ical.timeline.included(now, agenda_max_days): + upcoming.append(events) + if middle_section is 'Calendar' and events in ical.timeline.included(now, calendar_max_days): + upcoming.append(events) + + def event_begins(elem): + return elem.begin + + upcoming.sort(key=event_begins) + + else: + print("Could not fetch events from your iCalendar.") + print("Either the internet connection is too weak or we're offline.") + + + if middle_section is 'Agenda': + """For the agenda view, create a list containing dates and events of the next 22 days""" + if len(upcoming) is not 0: + while (upcoming[-1].begin.date().day - now.day) + len(upcoming) >= 22: + del upcoming[-1] + agenda_list = [] + for i in range(22): + date = now.replace(days=+i) + agenda_list.append({'value':date.format('ddd D MMM YY', locale=language),'type':'date'}) + for events in upcoming: + if events.begin.date().day == date.day: + if not events.all_day: + agenda_list.append({'value':events.begin.format('HH:mm')+ ' '+ str(events.name), 'type':'timed_event'}) + else: + agenda_list.append({'value':events.name, 'type':'full_day_event'}) + if bottom_section is not "": + del agenda_list[16:] + image.paste(seperator2, agenda_view_lines['line17']) + + if bottom_section is "": + del agenda_list[22:] + image.paste(seperator2, agenda_view_lines['line22']) + + for lines in range(len(agenda_list)): + if agenda_list[lines]['type'] is 'date': + write_text(384, 25, agenda_list[lines]['value'], agenda_view_lines['line'+str(lines+1)], font=semi, alignment='left') + image.paste(seperator2, agenda_view_lines['line'+str(lines+1)]) + elif agenda_list[lines]['type'] is 'timed_event': + write_text(384, 25, agenda_list[lines]['value'], agenda_view_lines['line'+str(lines+1)], alignment='left') + else: + write_text(384, 25, agenda_list[lines]['value'], agenda_view_lines['line'+str(lines+1)]) + + if middle_section is 'Calendar': + """Draw smaller squares on days with events""" + for numbers in events_this_month: + if numbers in cal[0]: + image.paste(eventicon, positions['a'+str(cal[0].index(numbers)+1)], eventicon) + if numbers in cal[1]: + image.paste(eventicon, positions['b'+str(cal[1].index(numbers)+1)], eventicon) + if numbers in cal[2]: + image.paste(eventicon, positions['c'+str(cal[2].index(numbers)+1)], eventicon) + if numbers in cal[3]: + image.paste(eventicon, positions['d'+str(cal[3].index(numbers)+1)], eventicon) + if numbers in cal[4]: + image.paste(eventicon, positions['e'+str(cal[4].index(numbers)+1)], eventicon) + if len(cal) is 6 and numbers in cal[5]: image.paste(eventicon, positions['f'+str(cal[5].index(numbers)+1)], eventicon) - """Draw a larger square on today's date""" - today = time.day - if today in cal[0]: - image.paste(dateicon, positions['a'+str(cal[0].index(today)+1)], dateicon) - if today in cal[1]: - image.paste(dateicon, positions['b'+str(cal[1].index(today)+1)], dateicon) - if today in cal[2]: - image.paste(dateicon, positions['c'+str(cal[2].index(today)+1)], dateicon) - if today in cal[3]: - image.paste(dateicon, positions['d'+str(cal[3].index(today)+1)], dateicon) - if today in cal[4]: - image.paste(dateicon, positions['e'+str(cal[4].index(today)+1)], dateicon) - if len(cal) is 6: - if today in cal[5]: - image.paste(dateicon, positions['f'+str(cal[5].index(today)+1)], dateicon) + """Write event dates and names on the E-Paper""" + if bottom_section is "Events": + if len(cal) is 5: + del upcoming[6:] + for dates in range(len(upcoming)): + readable_date = datetime.strptime(upcoming[dates]['date'], '%Y %m %d').strftime('%-d %b') + write_text(70, 25, readable_date, date_positions['d'+str(dates+1)]) + for events in range(len(upcoming)): + write_text(314, 25, (upcoming[events]['event']), event_positions['e'+str(events+1)], alignment = 'left') + + if len(cal) is 6: + del upcoming[4:] + for dates in range(len(upcoming)): + readable_date = datetime.strptime(upcoming[dates]['date'], '%Y %m %d').strftime('%-d %b') + write_text(70, 25, readable_date, date_positions['d'+str(dates+3)]) + for events in range(len(upcoming)): + write_text(314, 25, (upcoming[events]['event']), event_positions['e'+str(events+3)], alignment = 'left') + """ Map all pixels of the generated image to red, white and black @@ -396,7 +428,7 @@ def main(): if display_colours is "bw": buffer[np.logical_and(r > 240, g > 240)] = [255,255,255] #white buffer[g < 255] = [0,0,0] #black - + improved_image = Image.fromarray(buffer).rotate(270, expand=True) print('Initialising E-Paper Display') epd.init() @@ -407,20 +439,25 @@ def main(): print('______Powering off the E-Paper until the next loop______'+'\n') epd.sleep() - del events_this_month - del upcoming + if middle_section is 'Calendar': + del events_this_month + del upcoming + del weekday_names_list - if additional_feature is "rss": + if bottom_section is 'RSS': del rss_feed del news + if middle_section is 'Agenda': + del agenda_list + del buffer del image del improved_image gc.collect() if calibration_countdown is 'initial': - calibration_countdown = 0 + calibration_countdown = 0 calibration_countdown += 1 for i in range(1): @@ -433,7 +470,7 @@ def main(): for update_times in timings: if update_times >= mins: sleep_for_minutes = update_times - mins - + next_update_countdown = sleep_for_minutes*60 + (60-seconds) print(sleep_for_minutes,'Minutes and ', (60-seconds),'Seconds left until next loop') diff --git a/Calendar/OpenSans-Semibold.ttf b/Calendar/OpenSans-Semibold.ttf deleted file mode 100644 index 6b44ec1..0000000 Binary files a/Calendar/OpenSans-Semibold.ttf and /dev/null differ diff --git a/Calendar/Settings-Web-UI.html b/Calendar/Settings-Web-UI.html index ea9337b..d4fbca8 100644 --- a/Calendar/Settings-Web-UI.html +++ b/Calendar/Settings-Web-UI.html @@ -1,6 +1,7 @@ +Settings-File Generator