refactoring wip
This commit is contained in:
		| @@ -1,15 +1,12 @@ | |||||||
| #!/usr/bin/python3 |  | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| """ | """ | ||||||
| Inkycal ePaper driving functions | Inkycal ePaper driving functions | ||||||
| Copyright by aceisace | Copyright by aceisace | ||||||
| """ | """ | ||||||
|  | import asyncio | ||||||
| import os | import os | ||||||
| from importlib import import_module | from importlib import import_module | ||||||
| from PIL import Image |  | ||||||
|  |  | ||||||
| from inkycal.custom import top_level | from PIL import Image | ||||||
| import glob |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class Display: | class Display: | ||||||
| @@ -18,25 +15,20 @@ class Display: | |||||||
|     Creates an instance of the driver for the selected E-Paper model and allows |     Creates an instance of the driver for the selected E-Paper model and allows | ||||||
|     rendering images and calibrating the E-Paper display |     rendering images and calibrating the E-Paper display | ||||||
|  |  | ||||||
|     args: |     Args: | ||||||
|       - epaper_model: The name of your E-Paper model. |       - epaper_model: The name of your E-Paper model. | ||||||
|  |  | ||||||
|  |  | ||||||
|     """ |     """ | ||||||
|  |  | ||||||
|     def __init__(self, epaper_model): |     def __init__(self, epaper_model): | ||||||
|         """Load the drivers for this epaper model""" |         """Load the drivers for this epaper model""" | ||||||
|  |  | ||||||
|         if 'colour' in epaper_model: |  | ||||||
|             self.supports_colour = True |  | ||||||
|         else: |  | ||||||
|             self.supports_colour = False |  | ||||||
|  |  | ||||||
|         try: |         try: | ||||||
|             driver_path = f'inkycal.display.drivers.{epaper_model}' |             driver_path = f'inkycal.display.drivers.{epaper_model}' | ||||||
|             driver = import_module(driver_path) |             driver = import_module(driver_path) | ||||||
|             self._epaper = driver.EPD() |             self._epaper = driver.EPD() | ||||||
|             self.model_name = epaper_model |             self.model_name = epaper_model | ||||||
|  |             self.supported_colours = self._epaper.supported_colours | ||||||
|  |  | ||||||
|         except ImportError: |         except ImportError: | ||||||
|             raise Exception('This module is not supported. Check your spellings?') |             raise Exception('This module is not supported. Check your spellings?') | ||||||
| @@ -44,7 +36,7 @@ class Display: | |||||||
|         except FileNotFoundError: |         except FileNotFoundError: | ||||||
|             raise Exception('SPI could not be found. Please check if SPI is enabled') |             raise Exception('SPI could not be found. Please check if SPI is enabled') | ||||||
|  |  | ||||||
|     def render(self, im_black, im_colour=None): |     async def render(self, im_black: Image.Image, im_colour=Image.Image or None) -> None: | ||||||
|         """Renders an image on the selected E-Paper display. |         """Renders an image on the selected E-Paper display. | ||||||
|  |  | ||||||
|         Initlializes the E-Paper display, sends image data and executes command |         Initlializes the E-Paper display, sends image data and executes command | ||||||
| @@ -61,45 +53,46 @@ class Display: | |||||||
|  |  | ||||||
|         Rendering an image for black-white E-Paper displays: |         Rendering an image for black-white E-Paper displays: | ||||||
|  |  | ||||||
|         >>> sample_image = PIL.Image.open('path/to/file.png') |         >>> sample_image = Image.open('path/to/file.png') | ||||||
|         >>> display = Display('my_black_white_display') |         >>> display = Display('my_black_white_display') | ||||||
|         >>> display.render(sample_image) |         >>> display.render(sample_image) | ||||||
|  |  | ||||||
|  |  | ||||||
|         Rendering black-white on coloured E-Paper displays: |         Rendering black-white on coloured E-Paper displays: | ||||||
|  |  | ||||||
|         >>> sample_image = PIL.Image.open('path/to/file.png') |         >>> sample_image = Image.open('path/to/file.png') | ||||||
|         >>> display = Display('my_coloured_display') |         >>> display = Display('my_coloured_display') | ||||||
|         >>> display.render(sample_image, sample_image) |         >>> display.render(sample_image, sample_image) | ||||||
|  |  | ||||||
|  |  | ||||||
|         Rendering coloured image where 2 images are available: |         Rendering coloured image where 2 images are available: | ||||||
|  |  | ||||||
|         >>> black_image = PIL.Image.open('path/to/file.png') # black pixels |         >>> black_image = Image.open('path/to/file.png') # black pixels | ||||||
|         >>> colour_image = PIL.Image.open('path/to/file.png') # coloured pixels |         >>> colour_image = Image.open('path/to/file.png') # coloured pixels | ||||||
|         >>> display = Display('my_coloured_display') |         >>> display = Display('my_coloured_display') | ||||||
|         >>> display.render(black_image, colour_image) |         >>> display.render(black_image, colour_image) | ||||||
|         """ |         """ | ||||||
|  |  | ||||||
|         epaper = self._epaper |         epaper = self._epaper | ||||||
|  |  | ||||||
|         if not self.supports_colour: |  | ||||||
|             print('Initialising..', end='') |  | ||||||
|             epaper.init() |  | ||||||
|             print('Updating display......', end='') |  | ||||||
|             epaper.display(epaper.getbuffer(im_black)) |  | ||||||
|             print('Done') |  | ||||||
|  |  | ||||||
|         elif self.supports_colour: |         print('[Display] init..', end='') | ||||||
|             if not im_colour: |         epaper.init() | ||||||
|                 raise Exception('im_colour is required for coloured epaper displays') |         print('[Display] updating...', end='') | ||||||
|             print('Initialising..', end='') |  | ||||||
|             epaper.init() |  | ||||||
|             print('Updating display......', end='') |  | ||||||
|             epaper.display(epaper.getbuffer(im_black), epaper.getbuffer(im_colour)) |  | ||||||
|             print('Done') |  | ||||||
|  |  | ||||||
|         print('Sending E-Paper to deep sleep...', end='') |         try: | ||||||
|  |             loop = asyncio.get_event_loop() | ||||||
|  |             if len(self.supported_colours == 2): | ||||||
|  |                 loop.run_until_complete(asyncio.wait_for(epaper.display(epaper.getbuffer(im_black)), timeout=60)) | ||||||
|  |             else: | ||||||
|  |                 loop.run_until_complete(asyncio.wait_for(epaper.display(epaper.getbuffer(im_black), epaper.getbuffer(im_colour)), timeout=60)) | ||||||
|  |         except asyncio.TimeoutError: | ||||||
|  |             raise AssertionError("Failed to display an image on the display. This may be due to the following:" | ||||||
|  |                                  "- Incorrectly selected driver" | ||||||
|  |                                  "- Incorrect wiring (especially when not using the driver hat" | ||||||
|  |                                  "- Incorrectly inserted display cable. The display needs to face up when connecting the driver board") | ||||||
|  |  | ||||||
|  |         print('[Display] sleep mode', end='') | ||||||
|         epaper.sleep() |         epaper.sleep() | ||||||
|         print('Done') |         print('Done') | ||||||
|  |  | ||||||
| @@ -125,13 +118,13 @@ class Display: | |||||||
|         epaper = self._epaper |         epaper = self._epaper | ||||||
|         epaper.init() |         epaper.init() | ||||||
|  |  | ||||||
|         display_size = self.get_display_size(self.model_name) |         display_size = epaper.get_display_size() | ||||||
|  |  | ||||||
|         white = Image.new('1', display_size, 'white') |         white = Image.new('1', display_size, 'white') | ||||||
|         black = Image.new('1', display_size, 'black') |         black = Image.new('1', display_size, 'black') | ||||||
|  |  | ||||||
|         print('----------Started calibration of ePaper display----------') |         print('----------Started calibration of ePaper display----------') | ||||||
|         if self.supports_colour: |         for colour in epaper.supported_colours: | ||||||
|             for _ in range(cycles): |             for _ in range(cycles): | ||||||
|                 print('Calibrating...', end=' ') |                 print('Calibrating...', end=' ') | ||||||
|                 print('black...', end=' ') |                 print('black...', end=' ') | ||||||
| @@ -142,25 +135,12 @@ class Display: | |||||||
|                 epaper.display(epaper.getbuffer(white), epaper.getbuffer(white)) |                 epaper.display(epaper.getbuffer(white), epaper.getbuffer(white)) | ||||||
|                 print(f'Cycle {_ + 1} of {cycles} complete') |                 print(f'Cycle {_ + 1} of {cycles} complete') | ||||||
|  |  | ||||||
|         if not self.supports_colour: |  | ||||||
|             for _ in range(cycles): |  | ||||||
|                 print('Calibrating...', end=' ') |  | ||||||
|                 print('black...', end=' ') |  | ||||||
|                 epaper.display(epaper.getbuffer(black)) |  | ||||||
|                 print('white...') |  | ||||||
|                 epaper.display(epaper.getbuffer(white)), |  | ||||||
|                 print(f'Cycle {_ + 1} of {cycles} complete') |  | ||||||
|  |  | ||||||
|             print('-----------Calibration complete----------') |             print('-----------Calibration complete----------') | ||||||
|             epaper.sleep() |             epaper.sleep() | ||||||
|  |  | ||||||
|     @classmethod |     def get_display_size(self) -> tuple: | ||||||
|     def get_display_size(cls, model_name): |  | ||||||
|         """Returns the size of the display as a tuple -> (width, height) |         """Returns the size of the display as a tuple -> (width, height) | ||||||
|  |  | ||||||
|         Looks inside "drivers" folder for the given model name, then returns it's |  | ||||||
|         size. |  | ||||||
|  |  | ||||||
|         Args: |         Args: | ||||||
|           - model_name: str -> The name of the E-Paper display to get it's size. |           - model_name: str -> The name of the E-Paper display to get it's size. | ||||||
|  |  | ||||||
| @@ -171,29 +151,10 @@ class Display: | |||||||
|  |  | ||||||
|         >>> Display.get_display_size('model_name') |         >>> Display.get_display_size('model_name') | ||||||
|         """ |         """ | ||||||
|         if not isinstance(model_name, str): |         return self._epaper.EPD_WIDTH, self._epaper.EPD_HEIGHT | ||||||
|             print('model_name should be a string') |  | ||||||
|             return |  | ||||||
|         else: |  | ||||||
|             driver_files = top_level + '/inkycal/display/drivers/*.py' |  | ||||||
|             drivers = glob.glob(driver_files) |  | ||||||
|             drivers = [i.split('/')[-1].split('.')[0] for i in drivers] |  | ||||||
|             drivers.remove('__init__') |  | ||||||
|             drivers.remove('epdconfig') |  | ||||||
|             if model_name not in drivers: |  | ||||||
|                 print('This model name was not found. Please double check your spellings') |  | ||||||
|                 return |  | ||||||
|             else: |  | ||||||
|                 with open(top_level + '/inkycal/display/drivers/' + model_name + '.py') as file: |  | ||||||
|                     for line in file: |  | ||||||
|                         if 'EPD_WIDTH=' in line.replace(" ", ""): |  | ||||||
|                             width = int(line.rstrip().replace(" ", "").split('=')[-1]) |  | ||||||
|                         if 'EPD_HEIGHT=' in line.replace(" ", ""): |  | ||||||
|                             height = int(line.rstrip().replace(" ", "").split('=')[-1]) |  | ||||||
|                 return width, height |  | ||||||
|  |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def get_display_names(cls): |     def get_display_names(cls) -> list: | ||||||
|         """Prints all supported E-Paper models. |         """Prints all supported E-Paper models. | ||||||
|  |  | ||||||
|         Fetches all filenames in driver folder and prints them on the console. |         Fetches all filenames in driver folder and prints them on the console. | ||||||
| @@ -208,10 +169,14 @@ class Display: | |||||||
|  |  | ||||||
|         >>> Display.get_display_names() |         >>> Display.get_display_names() | ||||||
|         """ |         """ | ||||||
|         driver_files = top_level + '/inkycal/display/drivers/' |         current_dir = os.path.dirname(os.path.abspath(__file__)) | ||||||
|         drivers = [i for i in os.listdir(driver_files) if i.endswith(".py") and not i.startswith("__") and "_" in i] |  | ||||||
|  |         driver_files = f"{current_dir}/drivers" | ||||||
|  |         drivers = [i for i in os.listdir(driver_files) if i.endswith(".py") and i.startswith("inkycal") and "_" in i] | ||||||
|         return drivers |         return drivers | ||||||
|  |  | ||||||
|  |  | ||||||
| if __name__ == '__main__': | if __name__ == '__main__': | ||||||
|     print("Running Display class in standalone mode") |     print("Running Display class in standalone mode") | ||||||
|  |     a = Display.get_display_names() | ||||||
|  |     b = 1 | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								inkycal/display/test_display.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								inkycal/display/test_display.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | from unittest import TestCase | ||||||
|  |  | ||||||
|  | from inkycal import Display | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TestDisplay(TestCase): | ||||||
|  |  | ||||||
|  |     # def setUp(self) -> None: | ||||||
|  |     #     self.display = Display() | ||||||
|  |  | ||||||
|  |     def test_get_display_names(self): | ||||||
|  |  | ||||||
|  |         fetched_displays = Display.get_display_names() | ||||||
|  |         assert len(fetched_displays) >1 | ||||||
|  |         assert isinstance(fetched_displays, list) | ||||||
		Reference in New Issue
	
	Block a user