diff --git a/main.py b/main.py index e18cb54..02310f4 100755 --- a/main.py +++ b/main.py @@ -2,7 +2,7 @@ import asyncio import configparser -import os +import sys from rgbmatrix import ( RGBMatrixOptions, RGBMatrix @@ -32,6 +32,8 @@ logger.addHandler(sh) logger.addHandler(filehandler) +class OledExecption(Exception): + pass class Main(): def __init__(self, config) -> None: self.config = config @@ -40,6 +42,7 @@ def __init__(self, config) -> None: self.logger.setLevel(self.config['basic'].getint('loglevel')) else: self.logger.setLevel(10) + self.poll = None self.logger.debug(f"Logger is set to {self.logger.getEffectiveLevel()}") def parse_config_file(self): module = {} @@ -100,26 +103,48 @@ async def init_matrix(self, matrix): verified_modules.append(SportMatrix(matrix, modules['sport'], logger)) self.logger.info("Initalized matrixes") return verified_modules + + async def run_matrix_worker(self, matrix, polled_data): + self.logger.debug("Starting Worker") + # Need to make sure these need to be coroutines + matrix.render(polled_data) + + async def poll_api_worker(self, matrix): + polled_data = await matrix.poll_api() + return polled_data - async def main_run(self): - self.logger.info("Starting OhMyOled") - matrix = RGBMatrix(options=self.poll_rgbmatrix()) - self.logger.debug("Built Options for RGBMatrix") - matrixes = await self.init_matrix(matrix) - self.logger.info("Starting Matrixes...") - while True: - for matrix in matrixes: - poll = await matrix.poll_api() - matrix.render(poll) + async def main_run(self, loop): + try: + self.logger.info("Starting OhMyOled") + matrix = RGBMatrix(options=self.poll_rgbmatrix()) + self.logger.debug("Built Options for RGBMatrix") + matrixes = await self.init_matrix(matrix) + self.logger.info("Starting Matrixes...") + first_poll = True + while True: + for index, matrix in enumerate(matrixes): + if first_poll: + self.poll = await matrix.poll_api() + first_poll = False + if index + 1 >= len(matrixes): + tasks = [asyncio.create_task(matrix.render(self.poll, loop)), asyncio.create_task(matrixes[0].poll_api())] + else: + # Each one build a new function that can be called asynchrounously + tasks = [asyncio.create_task(matrix.render(self.poll, loop)), asyncio.create_task(matrixes[index+1].poll_api())] + _, self.poll = await asyncio.gather(*tasks) + except Exception as E: + logger.error(E) + loop.stop() if __name__ == "__main__": config = configparser.ConfigParser() logger.info("Pulling configuration /etc/ohmyoled/ohmyoled.conf") config.read('/etc/ohmyoled/ohmyoled.conf') main = Main(config) + loop = asyncio.get_event_loop() try: - loop.create_task(main.main_run()) + loop.create_task(main.main_run(loop)) loop.run_forever() except KeyboardInterrupt: logger.critical("Key Interrupt") diff --git a/matrix/matrix.py b/matrix/matrix.py index 923e5bf..f34e8c9 100755 --- a/matrix/matrix.py +++ b/matrix/matrix.py @@ -1,10 +1,9 @@ #!/usr/bin/python3 # ABS_Matrix -> Matrix_Module -# -# -# from abc import abstractmethod +import asyncio +import functools import configparser import logging from sys import exec_prefix @@ -134,8 +133,18 @@ def image_resize(self, width, height) -> None: self.set_image(self.image.resize((width, height), Image.ANTIALIAS)) self.set_draw(ImageDraw.Draw(self.image)) - def render_image(self, xoffset=0, yoffset=0): - self.matrix.SetImage(self.get_image, offset_y=yoffset, offset_x=xoffset) + async def render_image(self, loop=None, xoffset=0, yoffset=0): + if not loop: + loop = asyncio.get_event_loop() + await loop.run_in_executor( + None, + functools.partial( + self.matrix.SetImage, + self.get_image, + offset_x=xoffset, + offset_y=yoffset + ) + ) def draw_rectangle(self, position: List[Tuple]): """ diff --git a/matrix/sport/sportmatrix.py b/matrix/sport/sportmatrix.py index 70d271d..282cc41 100755 --- a/matrix/sport/sportmatrix.py +++ b/matrix/sport/sportmatrix.py @@ -178,7 +178,7 @@ def build_standings_image(self, api, xpos) -> Tuple[int, int]: ) return standings_image, (0, 25) - def render(self, api): + async def render(self, api, loop): self.clear() self.reload_image() if 'baseball'in api.sport: @@ -199,7 +199,7 @@ def render(self, api): ) for image, position in images: self.paste_image(image, position) - self.render_image() + await self.render_image() xpos +=1 xpos_for_top += 1 if xpos_for_top == 100: @@ -208,7 +208,7 @@ def render(self, api): else: font = ImageFont.truetype("/usr/share/fonts/fonts/04b24.otf", 14) self.draw_multiline_text((0, 0), "Basketball\nOffseason", font=font) - self.render_image() + await self.render_image() time.sleep(30) if 'basketball' in api.sport: # Check Data if Offseason if yes Diplay Offseason, Otherwise Display Data diff --git a/matrix/stock/stockmatrix.py b/matrix/stock/stockmatrix.py index 7650acd..0bfeacf 100755 --- a/matrix/stock/stockmatrix.py +++ b/matrix/stock/stockmatrix.py @@ -148,7 +148,7 @@ def render_lowest_price(self, api) -> None: fill=(255,0,0) ) - def render(self, api) -> None: + async def render(self, api, loop) -> None: self.logger.info("Started Render for Stock Matrix") self.clear() self.reload_image() @@ -157,5 +157,5 @@ def render(self, api) -> None: self.render_previous_close(api) self.render_highest_price(api) self.render_lowest_price(api) - self.render_image() + await self.render_image() time.sleep(30) \ No newline at end of file diff --git a/matrix/time.py b/matrix/time.py index f80c81b..363f833 100755 --- a/matrix/time.py +++ b/matrix/time.py @@ -30,7 +30,7 @@ async def poll_api(self): def build_fmt(self): return "%I:%M:%S %p" if TimeFormat.TWELEVE else "%H:%M:%S" - def render(self, poll): + async def render(self, poll, loop): # Build something that Loads in corner for all the modules loaded self.logger.info("Running Module TimeMatrix") counter = 0 @@ -41,6 +41,6 @@ def render(self, poll): self.set_draw(ImageDraw.Draw(self.get_image)) self.draw_text((3, 5), f"{self.return_time('%m/%d/%Y')}", font=font, fill=eval(self.config.get('color'))) self.draw_text((8, 16), f"{self.return_time('%I:%M:%S')}", font=font, fill=eval(self.config.get('color'))) - self.render_image() + await self.render_image() counter = counter + 1 time.sleep(1) \ No newline at end of file diff --git a/matrix/weathermatrix.py b/matrix/weathermatrix.py index 49a79b9..f5983e9 100755 --- a/matrix/weathermatrix.py +++ b/matrix/weathermatrix.py @@ -105,7 +105,7 @@ def render_time(self, api: Weather): self.draw_text((7, 23), sunrise, font=font) self.draw_text((35, 18), "\uf044", font=ImageFont.truetype("/usr/share/fonts/weathericons.ttf", 11), fill=(255, 145, 0)) self.draw_text((40, 23), sunset, font=font) - def render(self, api: Weather): + async def render(self, api: Weather, loop): self.logger.info("Rendering Weather Matrix") self.logger.debug("Clearing Image") self.clear() @@ -115,7 +115,7 @@ def render(self, api: Weather): self.render_icon(api) self.render_location(api) self.logger.info("Loading Screen 1 of Matrix") - self.render_image() + await self.render_image() time.sleep(30) self.clear() self.logger.debug("Reloading Image in matrix") @@ -126,6 +126,6 @@ def render(self, api: Weather): self.render_wind(api) self.render_time(api) self.logger.info("Loading Screen 2 of Matrix") - self.render_image() + await self.render_image() time.sleep(30)