diff --git a/Calendar/E-Paper.py b/Calendar/E-Paper.py index 5c12e50..8b77836 100644 --- a/Calendar/E-Paper.py +++ b/Calendar/E-Paper.py @@ -19,6 +19,7 @@ import random import gc import feedparser import numpy as np +from pytz import timezone from settings import * from image_data import * @@ -52,13 +53,20 @@ else: im_open = Image.open +'''Get system timezone and set timezone accordingly''' +file = open('/etc/timezone','r') +lines = file.readlines() +system_tz = lines[0].rstrip() +local_tz = timezone(system_tz) + + owm = pyowm.OWM(api_key) """Main loop starts from here""" def main(): calibration_countdown = 'initial' while True: - time = datetime.now() + time = datetime.now().replace(tzinfo=local_tz) hour = int(time.strftime("%-H")) month = int(time.now().strftime('%-m')) year = int(time.now().strftime('%Y')) @@ -179,7 +187,7 @@ def main(): """If no response was received from the openweathermap api server, add the cloud with question mark""" print('__________OWM-ERROR!__________'+'\n') - print('Reason: ',e+'\n') + print('Reason: ',e,'\n') image.paste(no_response, wiconplace) pass @@ -320,8 +328,10 @@ def main(): """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)) + + time_span_calendar = time + timedelta(days=int(events_max_range)) + time_span_agenda = time + timedelta(days=22) + if internet_available() is True: print('Internet connection test passed'+'\n') print('Fetching events from your calendar'+'\n') @@ -335,14 +345,27 @@ def main(): 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 events.begin.date().year == today.year and 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 middle_section is 'Agenda' and events in ical.timeline.included(now, agenda_max_days): + if middle_section is 'Agenda' and time <= events.end.datetime <= time_span_agenda: upcoming.append(events) - if middle_section is 'Calendar' and events in ical.timeline.included(now, calendar_max_days): + if middle_section is 'Calendar' and time <= events.end.datetime <= time_span_calendar: upcoming.append(events) + '''Fix some known bugs from ics.py''' + for events in upcoming: + if events.all_day and events.duration.days > 1: + events.end = events.end.replace(days=-2) + for i in range(1, events.duration.days): + cc = events.clone() + cc.begin = cc.begin.replace(days=+i) + upcoming.append(cc) + + for events in upcoming: + if events.begin.format('HH:mm') == '00:00': + events.make_all_day() + def event_begins(elem): return elem.begin @@ -352,7 +375,6 @@ def main(): 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: @@ -365,9 +387,13 @@ def main(): 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'}) + if hours is '24': + agenda_list.append({'value':events.begin.to(system_tz).format('HH:mm')+ ' '+ str(events.name), 'type':'timed_event'}) + if hours is '12': + agenda_list.append({'value':events.begin.to(system_tz).format('hh:mm a')+ ' '+ 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']) @@ -406,18 +432,18 @@ def main(): 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') + readable_date = upcoming[dates].begin.format('D MMM', locale=language) 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') + write_text(314, 25, upcoming[events].name, 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') + readable_date = upcoming[dates].begin.format('D MMM', locale=language) 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') + write_text(314, 25, upcoming[events].name, event_positions['e'+str(events+3)], alignment = 'left') """ diff --git a/Changelog.md b/Changelog.md index eea1c35..2f18d4b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,48 @@ The order is from latest to oldest and structured in the following way: * Version name with date of publishing * Sections with either 'added', 'fixed', 'updated' and 'changed' +## [1.6] Mid May 2019 + +### Added +* Added new design option: **Agenda-View**, which displays events in the next few days with timings +* Added support for multi-day events +* Added support for multiple languages +* Added support for localisation options (dates will be shown in the set language now) +* Added new fonts (NotoSans Semi & Noto Sans CJK) which support many languages (without displaying tofus) +* Added dynamic space management to minimise empty space on the generated image +* Added support for RSS-feeds. It is now possible to display them in the bottom section +* Added image pre-processing operation to allow displaying the generated image correctly on the E-Paper +* Added limit (in days) when fetching events from the iCalendar +* Added option to select the display-update interval* +* Added user-friendly Web-UI (webpage) for entering personal details easily (Credit to TobyChui) +* Added support for continuing the loop even if some details are missing in the settings file (api-key, rss-feed) +* Added support for relative path and removed explicit path +* Added support for timezones. events timings will be shown correctly using the system's set timezone +* Added support for 12/24 hours format for events + + +### Changed +* Changed E-Paper layout by splitting the image into three section: top-, middle, bottom. +* Changed the way the installer checks if a required package is installed (by test-importing it in python3) +* Changed the function which displays text on the Calendar +* Merged e-paper driver files (initially epd7in5b and epd7in5) into a single one (e_paper_drivers) +* Switched from image-based translations to text-based translation +* Changed algorithm for filtering events + +### Removed +* Removed (older) fonts which were not suitable for multiple languages +* (Temporary) removed support of recurring events due to some known bugs +* (Temporary) dropped support of the installer on Raspbian Jessie Lite due to some known bugs +* Removed image-based translations for month names + +### Fixed +* Fixed problems with iCalendar triggers by removing them altogether when parsing the iCalendar +* Fixed problems with outdated events + + +(*) Updating too frequently can cause ghosting, a problem specific to E-Paper displays where parts of the previous image can be seen on the current image. Ghosting can be fixed by 'calibrating' the E-Paper (displaying a single colour on the entire display) and is done by default. As a rule of thumb, one 'calibration' should be done for every 6 display-updates to maintain a crisp image. + + ## [1.5] Early February 2019 ### Added diff --git a/Installer-with-debug.sh b/Installer-with-debug.sh index 9472260..9a5bfc3 100644 --- a/Installer-with-debug.sh +++ b/Installer-with-debug.sh @@ -197,6 +197,24 @@ if [ "$option" = 1 ] || [ "$option" = 2 ]; then sudo pip3 install feedparser fi + #pytz for user pi + echo -e "\e[1;36m"Checking if pytz is installed for user pi"\e[0m" + if python3.5 -c "import pytz" &> /dev/null; then + echo 'pytz is installed, skipping installation of this package.' + else + echo 'pytz is not installed, attempting to install now' + pip3 install pytz + fi + + #pytz for user sudo + echo -e "\e[1;36m"Checking if pytz is installed for user sudo"\e[0m" + if sudo python3.5 -c "import pytz" &> /dev/null; then + echo 'pytz is installed, skipping installation of this package.' + else + echo 'pytz is not installed, attempting to install now' + sudo pip3 install pytz + fi + echo -e "\e[1;36m"Finished installing all dependencies"\e[0m" # Clone the repository, then delete some non-required files diff --git a/README.md b/README.md index 6e9be12..5bf88d1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,3 @@ -# Attention: -## This branch is currently in a transition state (new release). Please use the Installer only if you are a new user and know what you are doing. For all other users, please wait until this warning has disappeared and the new release has been tested thoroughly. Thanks for your understanding. -

@@ -9,7 +6,7 @@ [![Version](https://img.shields.io/github/release/aceisace/Inky-Calendar.svg)](https://github.com/aceisace/Inky-Calendar/releases) [![Python](https://img.shields.io/pypi/pyversions/pyowm.svg)](https://img.shields.io/pypi/pyversions/pyowm.svg) - [![Licence](https://img.shields.io/github/license/aceisace/Inky-Calendar.svg)](https://github.com/aceisace/Inky-Calendar/blob/master/LICENSE) + [![Licence](https://img.shields.io/github/license/aceisace/Inky-Calendar.svg)](https://github.com/aceisace/Inky-Calendar/blob/Stable/LICENSE) [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/SaadNaseer)

@@ -18,6 +15,7 @@ A software written in python3 that allows you to transform an E-Paper display (l This software fully supports the 3-Colour **and** 2-Colour version of the 7.5" E-Paper display from waveshare/gooddisplay and works with Raspberry Pi 2, 3 and 0 (Zero, Zero W, Zero WH). ## News: +* **Added Agenda-View design and support for multiple languages (Mid May 2019)** * **Updated and optimised the installer for faster installation and updating (Mid April 2019)** * **Added a user-friendly Web-UI for adding details to the programm** (Credit to TobyChui for the template) * **Version 1.5 released (Early February 2019) with a new layout, displayed events and many back-end improvements** @@ -47,7 +45,7 @@ This software fully supports the 3-Colour **and** 2-Colour version of the 7.5" E # Setup ## Getting the Raspberry Pi Zero W ready -1. After [flashing Raspbian Stretch (Lite or Desktop)](https://www.raspberrypi.org/downloads/raspbian/), set up Wifi on the Raspberry Pi Zero W by copying the file **wpa_supplicant.conf** (from above) to the /boot directory and adding your Wifi details in that file. +1. After [flashing Raspbian Stretch (with Desktop)](https://www.raspberrypi.org/downloads/raspbian/), set up Wifi on the Raspberry Pi Zero W by copying the file **wpa_supplicant.conf** (from above) to the /boot directory and adding your Wifi details in that file. 2. Create a simple text document named **ssh** in the boot directory to enable ssh. 3. Expand the filesystem in the Terminal with **`sudo raspi-config --expand-rootfs`** 4. Enable SPI by entering **`sudo sed -i s/#dtparam=spi=on/dtparam=spi=on/ /boot/config.txt`** in the Terminal @@ -57,7 +55,7 @@ This software fully supports the 3-Colour **and** 2-Colour version of the 7.5" E **[Disable on-board-led](https://www.jeffgeerling.com/blogs/jeff-geerling/controlling-pwr-act-leds-raspberry-pi)** ## Installing required packages for python 3.x -Execute the following command in the Terminal to install all required packages. This will work on both, Raspbian Stretch with Desktop and Raspbian Stretch lite, although Raspbian Desktop is recommended. +Execute the following command in the Terminal to install all required packages. Please use Raspbian Stretch with Desktop (preferably the latest version). Support for Raspbian Stretch Lite is temporarily dropped due to some changes, but will be available again soon once it has been tested. **`bash -c "$(curl -sL https://raw.githubusercontent.com/aceisace/Inky-Calendar/Stable/Installer-with-debug.sh)"`** @@ -72,25 +70,6 @@ To add details to the programm, please use the web-ui (user-interface). Simply d python3.5 /home/pi/Inky-Calendar/Calendar/E-Paper.py. If you encounter any issues, please leave a comment in the issues or via email. Thanks in advance. -## This part will soon shift to the settings web-ui -| Parameter | Description | -| :---: | :---: | -| ical_urls | Your iCalendar URL/s. To add more than one URL, seperate each with a comma, for example: ical-url1, ical-url2| -| rss_feeds | Here, you can add RSS-feed URLs which are used to fetch news etc. for example: rss-url1, rss-url2| -| update_interval | How often should be Display be updated in one hour? The default option is `60`, which means once every hour. You can select one of the values from: `10`, `15`, `20`, `30`, `60`. Please note that ghosting will occur when updating too frequently. To prevent ghosting, it's recommended to run 1 calibration for every 6 updates. For example, with an update interval of 1 hour, the calibration should be executed every 6 hours. | -| api_key | Your __personal__ openweathermap API-key which you can generate and find in your Account info | -| location | Location refers to the closest weather station from your place. It isn't necessarily the place you live in. To find this location, type your city name in the search box on [openweathermap](https://openweathermap.org/). The output should be in the following format: City Name, Country ISO-Code. Not sure what your ISO code is? Check here: [(find iso-code)](https://countrycode.org/) | -| week_starts_on | When does the week start on your Region? Possible options are `Monday` or `Sunday`| -| events_max_range | How far in the future should events from your iCalendar be fetched. The value is given in days. By default, events in the next 60 days will be fetched from the Calendar. Can be any integer from `1` to `365`| -| calibration_hours | At which hours would you like the Display to 'calibrate' itself? Calibration is strongly recommended at least 3 times a day. In the list, you have to include hours in 24-hour format, seperated by a comma. The default option is `1,12,18` and refers to 1 am, 12 am, and 6 pm | -| display_colours | This should normally be set by the installer when you choose the type of your display. Options include `black-white` if you're using the black and white E-Paper or `black-white-red/yellow` when you're using the black-white-red or black-white-yellow E-Paper| -| language | Choosing the language allows changing the language of the month and week-icons. Possible options are `en` for english, `de` for german and `zh-tw` for Taiwan Chinese (Hong Kong Chinese)| -| units| Selecting units allows switching units from km/h (kilometer per hour) and °C (degree Celcius) to mph (miles per hour) and °F (degree Fahrenheit). Possible options are `metric` or `imperial`| -| hours | Which time format do you prefer? This will change the sunrise and sunset times from 24-hours format to 12-hours format. Possible options are `24` for 24-hours and `12` for 12-hours.| -| top_section | What would you like the Display to show in the top section? Currently, only weather is available| -| middle_section | What would you like the Display to show in the main section? The default option is `Calendar` (for RSS-feeds. You may choose `Agenda` if you want to display events instead of the Calendar | -| bottom_section | What would you like the Display to show in the bottom section? | - ## iCalendar Currently, only Google Calendar is fully supported and has proven to run more stable than others. While it is possible that a non-Google iCalendar may work, it is often not the case. If you're not using Google-Calendar and the script is throwing errors related to your iCalendar, please export your iCalendar (as an .ics file), create a new Calendar at Google Calendar and import your previous Calendar's .ics file. After importing, navigate to the section 'Integrate Calendar', copy the 'Secret address in iCal format' and paste it in the ical_urls section in the settings.py file (see instructions above). @@ -114,7 +93,7 @@ The average response time for issues, PRs and emails is usually 24 hours. In rar ### Don't forget to check out the Wiki. It contains all the information to understanding and customising the script. -**P.S:** Don't forget to star and watch the repo. For those who have done so already, thank you very much! +**P.S:** Don't forget to star and/or watch the repo. For those who have done so already, thank you very much! ## Contact * Email: aceisace63@yahoo.com (average response time < 24 hours)