diff --git a/README.md b/README.md index 8dce493..db7642f 100644 --- a/README.md +++ b/README.md @@ -45,13 +45,13 @@ Inkycal is fully modular, you can mix and match any modules you like and configu ## Configuring the Raspberry Pi 1. Flash Raspberry Pi OS according to the [instructions](https://www.raspberrypi.org/software/). Leave the SD card plugged in your computer. 2. Create and download `settings.json` file for Inkycal from the [WEB-UI](https://aceisace.eu.pythonanywhere.com/inkycal-config-v2-0-0) -4. Download the `ssh` text file from the [WEB-UI](https://aceisace.eu.pythonanywhere.com/create_ssh) -5. Create and download a WiFi-configuration file (`wpa_supplicant.conf`) from the [WEB-UI](https://aceisace.eu.pythonanywhere.com/setup_wifi) -6. Copy these three downloaded files to the flashed microSD card. On Windows, this is the only visible directory on the SD card. On Linux, copy these files to `/boot` -7. Eject the microSD card from your computer now, insert it in the Raspberry Pi and power the Raspberry Pi. -8. Once the green LED has stopped blinking after ~3 minutes, use an SSH client to connect to the Raspberry Pi. On Windows, you can use PUTTY, but you can also use an SSH App +3. Download the `ssh` text file from the [WEB-UI](https://aceisace.eu.pythonanywhere.com/create_ssh) +4. Create and download a WiFi-configuration file (`wpa_supplicant.conf`) from the [WEB-UI](https://aceisace.eu.pythonanywhere.com/setup_wifi) +5. Copy these three downloaded files to the flashed microSD card. On Windows, this is the only visible directory on the SD card. On Linux, copy these files to `/boot` +6. Eject the microSD card from your computer now, insert it in the Raspberry Pi and power the Raspberry Pi. +7. Once the green LED has stopped blinking after ~3 minutes, use an SSH client to connect to the Raspberry Pi. On Windows, you can use PUTTY, but you can also use an SSH App on your smartphone. Use the address: `raspberrypi.local` with `pi` as the username and `raspberry` as the password. For more detailed instructions, check out the page from the [Raspberry Pi website](https://www.raspberrypi.org/documentation/remote-access/ssh/) -9. After connecting via SSH, run the following commands, line by line: +8. After connecting via SSH, run the following commands, line by line: ```bash sudo raspi-config --expand-rootfs sudo sed -i s/#dtparam=spi=on/dtparam=spi=on/ /boot/config.txt @@ -82,6 +82,9 @@ source venv/bin/activate python -m pip install --upgrade pip pip install wheel pip install -e ./ + +# If you are running on the Raspberry Pi, please install the following too to allow rendering on the display +pip install RPi.GPIO==0.7.1 spidev==3.5 ``` ## Running Inkycal diff --git a/inkycal/custom/functions.py b/inkycal/custom/functions.py index 9d6b9c4..7054fd5 100644 --- a/inkycal/custom/functions.py +++ b/inkycal/custom/functions.py @@ -151,7 +151,7 @@ def write(image, xy, box_size, text, font=None, **kwargs): box_width, box_height = box_size # Increase fontsize to fit specified height and width of text box - if (autofit == True) or (fill_width != 1.0) or (fill_height != 0.8): + if autofit or (fill_width != 1.0) or (fill_height != 0.8): size = 8 font = ImageFont.truetype(font.path, size) text_width, text_height = font.getsize(text)[0], font.getsize('hg')[1] @@ -169,7 +169,7 @@ def write(image, xy, box_size, text, font=None, **kwargs): while (text_width, text_height) > (box_width, box_height): text = text[0:-1] text_width, text_height = font.getsize(text)[0], font.getsize('hg')[1] - logs.debug((text)) + logs.debug(text) # Align text to desired position if alignment == "center" or None: @@ -192,7 +192,7 @@ def write(image, xy, box_size, text, font=None, **kwargs): # space = Image.new('RGBA', (box_width, box_height), color= 'red') # ImageDraw.Draw(space).text((x, y), text, fill='white', font=font) - if rotation != None: + if rotation: space.rotate(rotation, expand=True) # Update only region with text (add text with transparent background) diff --git a/inkycal/display/drivers/epdconfig_12_in_48.py b/inkycal/display/drivers/epdconfig_12_in_48.py index 4bc59a8..c490133 100644 --- a/inkycal/display/drivers/epdconfig_12_in_48.py +++ b/inkycal/display/drivers/epdconfig_12_in_48.py @@ -34,53 +34,65 @@ import sys from ctypes import * -EPD_SCK_PIN =11 -EPD_MOSI_PIN =10 +EPD_SCK_PIN = 11 +EPD_MOSI_PIN = 10 -EPD_M1_CS_PIN =8 -EPD_S1_CS_PIN =7 -EPD_M2_CS_PIN =17 -EPD_S2_CS_PIN =18 +EPD_M1_CS_PIN = 8 +EPD_S1_CS_PIN = 7 +EPD_M2_CS_PIN = 17 +EPD_S2_CS_PIN = 18 -EPD_M1S1_DC_PIN =13 -EPD_M2S2_DC_PIN =22 +EPD_M1S1_DC_PIN = 13 +EPD_M2S2_DC_PIN = 22 -EPD_M1S1_RST_PIN =6 -EPD_M2S2_RST_PIN =23 +EPD_M1S1_RST_PIN = 6 +EPD_M2S2_RST_PIN = 23 -EPD_M1_BUSY_PIN =5 -EPD_S1_BUSY_PIN =19 -EPD_M2_BUSY_PIN =27 -EPD_S2_BUSY_PIN =24 +EPD_M1_BUSY_PIN = 5 +EPD_S1_BUSY_PIN = 19 +EPD_M2_BUSY_PIN = 27 +EPD_S2_BUSY_PIN = 24 -additional_driver_path = f"{os.path.dirname(os.path.realpath(__file__))}/epd_12_in_48_lib.so" +find_dirs = [ + os.path.dirname(os.path.realpath(__file__)), + '/usr/local/lib', + '/usr/lib', +] +spi = None +for find_dir in find_dirs: + so_filename = os.path.join(find_dir, 'epd_12_in_48_lib.so') + if os.path.exists(so_filename): + spi = CDLL(so_filename) + break +if spi is None: + RuntimeError('Cannot find epd_12_in_48_lib.so') -if not os.path.exists(additional_driver_path): - RuntimeError("Inkycal cannot find the additional driver files for 12in48 3-colour") - -spi = CDLL(additional_driver_path) def digital_write(pin, value): GPIO.output(pin, value) + def digital_read(pin): return GPIO.input(pin) -def spi_writebyte(value): + +def spi_writebyte(value): spi.DEV_SPI_WriteByte(value) - + + def delay_ms(delaytime): time.sleep(delaytime / 1000.0) - + + def module_init(): GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) - GPIO.setup(EPD_SCK_PIN, GPIO.OUT) + GPIO.setup(EPD_SCK_PIN, GPIO.OUT) GPIO.setup(EPD_MOSI_PIN, GPIO.OUT) - + logging.debug("python call wiringPi Lib") - - GPIO.setup(EPD_M2S2_RST_PIN, GPIO.OUT) + + GPIO.setup(EPD_M2S2_RST_PIN, GPIO.OUT) GPIO.setup(EPD_M1S1_RST_PIN, GPIO.OUT) GPIO.setup(EPD_M2S2_DC_PIN, GPIO.OUT) GPIO.setup(EPD_M1S1_DC_PIN, GPIO.OUT) @@ -93,12 +105,12 @@ def module_init(): GPIO.setup(EPD_S2_BUSY_PIN, GPIO.IN) GPIO.setup(EPD_M1_BUSY_PIN, GPIO.IN) GPIO.setup(EPD_M2_BUSY_PIN, GPIO.IN) - + digital_write(EPD_M1_CS_PIN, 1) digital_write(EPD_S1_CS_PIN, 1) digital_write(EPD_M2_CS_PIN, 1) digital_write(EPD_S2_CS_PIN, 1) - + digital_write(EPD_M2S2_RST_PIN, 0) digital_write(EPD_M1S1_RST_PIN, 0) digital_write(EPD_M2S2_DC_PIN, 1) @@ -106,6 +118,7 @@ def module_init(): spi.DEV_ModuleInit() + def module_exit(): digital_write(EPD_M2S2_RST_PIN, 0) digital_write(EPD_M1S1_RST_PIN, 0) @@ -116,25 +129,25 @@ def module_exit(): digital_write(EPD_M1_CS_PIN, 1) digital_write(EPD_M2_CS_PIN, 1) + def spi_readbyte(Reg): GPIO.setup(EPD_MOSI_PIN, GPIO.IN) - j=0 + j = 0 # time.sleep(0.01) for i in range(0, 8): - GPIO.output(EPD_SCK_PIN, GPIO.LOW) + GPIO.output(EPD_SCK_PIN, GPIO.LOW) # time.sleep(0.01) - j = j << 1 - if(GPIO.input(EPD_MOSI_PIN) == GPIO.HIGH): + j = j << 1 + if (GPIO.input(EPD_MOSI_PIN) == GPIO.HIGH): j |= 0x01 else: - j &= 0xfe - # time.sleep(0.01) - GPIO.output(EPD_SCK_PIN, GPIO.HIGH) + j &= 0xfe + # time.sleep(0.01) + GPIO.output(EPD_SCK_PIN, GPIO.HIGH) # time.sleep(0.01) GPIO.setup(EPD_MOSI_PIN, GPIO.OUT) - return j - + return j + + def delay_ms(delaytime): time.sleep(delaytime / 1000.0) - - diff --git a/inkycal/main.py b/inkycal/main.py index 58d0929..da936c1 100644 --- a/inkycal/main.py +++ b/inkycal/main.py @@ -9,33 +9,17 @@ Copyright by aceisace import glob import hashlib import json -import os import traceback from logging.handlers import RotatingFileHandler import arrow +import numpy from inkycal.custom import * from inkycal.display import Display from inkycal.modules.inky_image import Inkyimage as Images -try: - from PIL import Image -except ImportError: - print('Pillow is not installed! Please install with:') - print('pip3 install Pillow') - -try: - import numpy -except ImportError: - print('numpy is not installed!. \nIf you are on Windows ' - 'run: pip3 install numpy \nIf you are on Raspberry Pi ' - 'remove numpy: pip3 uninstall numpy \nThen try again.') - -# (i): Logging shows logs above a threshold level. -# e.g. logging.DEBUG will show all from DEBUG until CRITICAL -# e.g. logging.ERROR will show from ERROR until CRITICAL -# #DEBUG > #INFO > #ERROR > #WARNING > #CRITICAL +from PIL import Image # On the console, set a logger to show only important logs # (level ERROR or higher) @@ -51,6 +35,10 @@ if on_rtd: handlers=[stream_handler]) else: + + if not os.path.exists(f'{top_level}/logs'): + os.mkdir(f'{top_level}/logs') + # Save all logs to a file, which contains more detailed output logging.basicConfig( level=logging.INFO, diff --git a/inkycal/modules/inkycal_feeds.py b/inkycal/modules/inkycal_feeds.py index c2a8dd2..b71b4d8 100644 --- a/inkycal/modules/inkycal_feeds.py +++ b/inkycal/modules/inkycal_feeds.py @@ -112,10 +112,9 @@ class Feeds(inkycal_module): parsed_feeds.append(f"•{posts.title}: {re.sub('<[^<]+?>', '', posts.summary)}") # if "description" in posts: - parsed_feeds = [i.split("\n") for i in parsed_feeds][0] - parsed_feeds = [i for i in parsed_feeds if i] - - self._parsed_feeds = parsed_feeds + if parsed_feeds: + parsed_feeds = [i.split("\n") for i in parsed_feeds][0] + parsed_feeds = [i for i in parsed_feeds if i] # Shuffle the list to prevent showing the same content if self.shuffle_feeds: @@ -134,7 +133,6 @@ class Feeds(inkycal_module): if counter < max_lines: filtered_feeds.append(wrapped) filtered_feeds = flatten(filtered_feeds) - self._filtered_feeds = filtered_feeds logger.debug(f'filtered feeds -> {filtered_feeds}') diff --git a/inkycal/modules/inkycal_todoist.py b/inkycal/modules/inkycal_todoist.py index 808baa5..dac1c31 100644 --- a/inkycal/modules/inkycal_todoist.py +++ b/inkycal/modules/inkycal_todoist.py @@ -16,7 +16,7 @@ logger = logging.getLogger(__name__) class Todoist(inkycal_module): """Todoist api class - parses todo's from api-key + parses todos from the todoist api. """ name = "Todoist API - show your todos from todoist" diff --git a/requirements.txt b/requirements.txt index 0f60340..7166c5b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,31 +1,30 @@ -arrow==1.2.2 -certifi==2021.10.8 -charset-normalizer==2.0.12 +arrow==1.2.3 +certifi==2022.12.7 cycler==0.11.0 -feedparser==6.0.8 -fonttools==4.32.0 +feedparser==6.0.10 +fonttools==4.38.0 geojson==2.5.0 -icalendar==4.0.9 -kiwisolver==1.4.2 -lxml==4.8.0 -matplotlib==3.5.1 -multitasking==0.0.10 -numpy==1.22.3 -packaging==21.3 -pandas==1.3.5 -Pillow==9.2.0 +icalendar==5.0.4 +kiwisolver==1.4.4 +lxml==4.9.2 +matplotlib==3.6.2 +multitasking==0.0.11 +numpy==1.24.1 +packaging==23.0 +pandas==1.5.2 +Pillow==9.4.0 pyowm==3.3.0 -pyparsing==3.0.7 +pyparsing==3.0.9 PySocks==1.7.1 python-dateutil==2.8.2 -pytz==2022.1 +pytz==2022.7 recurring-ical-events==0.1.17b0 -requests==2.27.1 -RPi.GPIO==0.7.1 +requests==2.28.1 +#RPi.GPIO==0.7.1 sgmllib3k==1.0.0 six==1.16.0 -spidev==3.5 -todoist-api-python==2.0.0 -typing_extensions==4.1.1 -urllib3==1.26.9 -yfinance==0.1.70 \ No newline at end of file +# spidev==3.5 +todoist-api-python==2.0.2 +typing_extensions==4.4.0 +urllib3==1.26.13 +yfinance==0.2.3 \ No newline at end of file