Merge pull request #35 from aceisace/Stable

Syncing branches
This commit is contained in:
Ace 2019-05-24 00:44:17 +02:00 committed by GitHub
commit c12b25308f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 104 additions and 39 deletions

View File

@ -19,6 +19,7 @@ import random
import gc import gc
import feedparser import feedparser
import numpy as np import numpy as np
from pytz import timezone
from settings import * from settings import *
from image_data import * from image_data import *
@ -52,13 +53,20 @@ else:
im_open = Image.open 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) owm = pyowm.OWM(api_key)
"""Main loop starts from here""" """Main loop starts from here"""
def main(): def main():
calibration_countdown = 'initial' calibration_countdown = 'initial'
while True: while True:
time = datetime.now() time = datetime.now().replace(tzinfo=local_tz)
hour = int(time.strftime("%-H")) hour = int(time.strftime("%-H"))
month = int(time.now().strftime('%-m')) month = int(time.now().strftime('%-m'))
year = int(time.now().strftime('%Y')) year = int(time.now().strftime('%Y'))
@ -179,7 +187,7 @@ def main():
"""If no response was received from the openweathermap """If no response was received from the openweathermap
api server, add the cloud with question mark""" api server, add the cloud with question mark"""
print('__________OWM-ERROR!__________'+'\n') print('__________OWM-ERROR!__________'+'\n')
print('Reason: ',e+'\n') print('Reason: ',e,'\n')
image.paste(no_response, wiconplace) image.paste(no_response, wiconplace)
pass pass
@ -320,8 +328,10 @@ def main():
"""Create a time span using the events_max_range value (in days) """Create a time span using the events_max_range value (in days)
to filter events in that range""" 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: if internet_available() is True:
print('Internet connection test passed'+'\n') print('Internet connection test passed'+'\n')
print('Fetching events from your calendar'+'\n') print('Fetching events from your calendar'+'\n')
@ -335,14 +345,27 @@ def main():
decode = decode[:beginAlarmIndex] + decode[endAlarmIndex+12:] decode = decode[:beginAlarmIndex] + decode[endAlarmIndex+12:]
ical = Calendar(decode) ical = Calendar(decode)
for events in ical.events: 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: if int((events.begin).format('D')) not in events_this_month:
events_this_month.append(int((events.begin).format('D'))) 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) 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) 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): def event_begins(elem):
return elem.begin return elem.begin
@ -352,7 +375,6 @@ def main():
print("Could not fetch events from your iCalendar.") print("Could not fetch events from your iCalendar.")
print("Either the internet connection is too weak or we're offline.") print("Either the internet connection is too weak or we're offline.")
if middle_section is 'Agenda': if middle_section is 'Agenda':
"""For the agenda view, create a list containing dates and events of the next 22 days""" """For the agenda view, create a list containing dates and events of the next 22 days"""
if len(upcoming) is not 0: if len(upcoming) is not 0:
@ -365,9 +387,13 @@ def main():
for events in upcoming: for events in upcoming:
if events.begin.date().day == date.day: if events.begin.date().day == date.day:
if not events.all_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: else:
agenda_list.append({'value':events.name, 'type':'full_day_event'}) agenda_list.append({'value':events.name, 'type':'full_day_event'})
if bottom_section is not "": if bottom_section is not "":
del agenda_list[16:] del agenda_list[16:]
image.paste(seperator2, agenda_view_lines['line17']) image.paste(seperator2, agenda_view_lines['line17'])
@ -406,18 +432,18 @@ def main():
if len(cal) is 5: if len(cal) is 5:
del upcoming[6:] del upcoming[6:]
for dates in range(len(upcoming)): 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)]) write_text(70, 25, readable_date, date_positions['d'+str(dates+1)])
for events in range(len(upcoming)): 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: if len(cal) is 6:
del upcoming[4:] del upcoming[4:]
for dates in range(len(upcoming)): 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)]) write_text(70, 25, readable_date, date_positions['d'+str(dates+3)])
for events in range(len(upcoming)): 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')
""" """

View File

@ -4,6 +4,48 @@ The order is from latest to oldest and structured in the following way:
* Version name with date of publishing * Version name with date of publishing
* Sections with either 'added', 'fixed', 'updated' and 'changed' * 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 ## [1.5] Early February 2019
### Added ### Added

View File

@ -197,6 +197,24 @@ if [ "$option" = 1 ] || [ "$option" = 2 ]; then
sudo pip3 install feedparser sudo pip3 install feedparser
fi 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" echo -e "\e[1;36m"Finished installing all dependencies"\e[0m"
# Clone the repository, then delete some non-required files # Clone the repository, then delete some non-required files

View File

@ -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.
<p align="center"> <p align="center">
<img src="https://github.com/aceisace/Inky-Calendar/blob/Stable/Gallery/Inky-Calendar-logo.png" width="800"> <img src="https://github.com/aceisace/Inky-Calendar/blob/Stable/Gallery/Inky-Calendar-logo.png" width="800">
</p> </p>
@ -9,7 +6,7 @@
[![Version](https://img.shields.io/github/release/aceisace/Inky-Calendar.svg)](https://github.com/aceisace/Inky-Calendar/releases) [![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) [![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) [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/SaadNaseer)
</p> </p>
@ -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). 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: ## 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)** * **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) * **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** * **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 # Setup
## Getting the Raspberry Pi Zero W ready ## 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. 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`** 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 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)** **[Disable on-board-led](https://www.jeffgeerling.com/blogs/jeff-geerling/controlling-pwr-act-leds-raspberry-pi)**
## Installing required packages for python 3.x ## 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)"`** **`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. 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. 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 ## 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). 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. ### 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 ## Contact
* Email: aceisace63@yahoo.com (average response time < 24 hours) * Email: aceisace63@yahoo.com (average response time < 24 hours)