Added main file (work in progress!)
Work in progress! Serves as the main file for inkycal.
This commit is contained in:
parent
63ccf534db
commit
ef743378f5
189
inkycal/main.py
Normal file
189
inkycal/main.py
Normal file
@ -0,0 +1,189 @@
|
||||
from config import Settings, Layout
|
||||
from inkycal.custom import *
|
||||
|
||||
import os.path.exists
|
||||
import traceback
|
||||
import logging
|
||||
import arrow
|
||||
import time
|
||||
|
||||
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! Please install with:')
|
||||
print('pip3 install numpy')
|
||||
|
||||
logger = logging.getLogger('inkycal')
|
||||
logger.setLevel(level=logging.DEBUG)
|
||||
|
||||
class inkycal:
|
||||
"""Main class"""
|
||||
|
||||
def __init__(self, settings_path, render=False):
|
||||
"""initialise class
|
||||
settings_path = str -> location/folder of settings file
|
||||
render = bool -> show something on the ePaper?
|
||||
"""
|
||||
# Check if render is boolean
|
||||
if not isinstance(render, bool):
|
||||
raise Exception('render must be True or False, not "{}"'.format(render))
|
||||
self.render = render
|
||||
|
||||
# load+validate settings file. Import and setup specified modules
|
||||
self.Settings = Settings(settings_path)
|
||||
self.active_modules = self.Settings.active_modules()
|
||||
for module in self.active_modules:
|
||||
try:
|
||||
loader = 'from modules import {0}'.format(module)
|
||||
module_data = self.Settings.get_config(module)
|
||||
size, conf = module_data['size'], module_data['config']
|
||||
setup = 'self.{} = {}(size, conf)'.format(module, module)
|
||||
exec(loader)
|
||||
exec(setup)
|
||||
logger.debug(('{}: size: {}, config: {}'.format(module, size, conf)))
|
||||
|
||||
# If a module was not found, print an error message
|
||||
except ImportError:
|
||||
print(
|
||||
'Could not find module: "{}". Please try to import manually.'.format(
|
||||
module))
|
||||
|
||||
# Give an OK message
|
||||
print('loaded inkycal')
|
||||
|
||||
|
||||
def countdown(self, interval_mins=None ):
|
||||
"""Returns the remaining time in seconds until next display update"""
|
||||
|
||||
# Validate update interval
|
||||
allowed_intervals = [10, 15, 20, 30, 60]
|
||||
|
||||
# Check if empty, if empty, use value from settings file
|
||||
if interval_mins == None:
|
||||
interval_mins = self.Settings.update_interval
|
||||
|
||||
# Check if integer
|
||||
if not isinstance(interval_mins, int):
|
||||
raise Exception('Update interval must be an integer -> 60')
|
||||
|
||||
# Check if value is supported
|
||||
if interval_mins not in allowed_intervals:
|
||||
raise Exception('Update interval is {}, but should be one of: {}'.format(
|
||||
interval_mins, allowed_intervals))
|
||||
|
||||
# Find out at which minutes the update should happen
|
||||
now = arrow.now()
|
||||
update_timings = [(60 - int(interval_mins)*updates) for updates in
|
||||
range(60//int(interval_mins))][::-1]
|
||||
|
||||
# Calculate time in mins until next update
|
||||
minutes = [_ for _ in update_timings if _>= now.minute][0] - now.minute
|
||||
|
||||
# Print the remaining time in mins until next update
|
||||
print('{0} Minutes left until next refresh'.format(minutes))
|
||||
|
||||
# Calculate time in seconds until next update
|
||||
remaining_time = minutes*60 + (60 - now.second)
|
||||
|
||||
# Return seconds until next update
|
||||
return remaining_time
|
||||
|
||||
def test(self):
|
||||
"""Test if inkycal can be run correctly"""
|
||||
|
||||
for module in self.active_modules:
|
||||
generate_im = 'self.{0}.generate_image()'.format(module)
|
||||
print('generating image for {} module...'.format(module), end = '')
|
||||
try:
|
||||
exec(generate_im)
|
||||
print('OK!')
|
||||
except Exception as Error:
|
||||
print('Error!')
|
||||
print(traceback.format_exc())
|
||||
|
||||
def run(self, render = True):
|
||||
"""Runs the main inykcal program nonstop (cannot be stopped anymore!)
|
||||
Set render to True to show something on the display"""
|
||||
|
||||
# TODO: rendering
|
||||
# TODO: printing traceback on display (or at least a smaller message?)
|
||||
# Upside down
|
||||
# Calibration
|
||||
# Stitch images together ,merge black&colour if required
|
||||
|
||||
# Count the number of times without any crashs
|
||||
counter = 1
|
||||
|
||||
while True:
|
||||
print('Generating images for all modules...')
|
||||
for module in self.active_modules:
|
||||
generate_im = 'self.{0}.generate_image()'.format(module)
|
||||
try:
|
||||
exec(generate_im)
|
||||
except Exception as Error:
|
||||
print('Error!')
|
||||
message = traceback.format_exc()
|
||||
print(message)
|
||||
counter = 0
|
||||
print('OK')
|
||||
|
||||
if render == True:
|
||||
print('rendering....')
|
||||
## if upside_down == True:
|
||||
## image = image.rotate(180, expand=True)
|
||||
## if three_colour_support == True:
|
||||
## image_col = image_col.rotate(180, expand=True)
|
||||
|
||||
print('\ninkycal has been running without any errors for', end = ' ')
|
||||
print('{} display_updates'.format(counter))
|
||||
counter += 1
|
||||
|
||||
sleep_time = self.countdown(10) #####
|
||||
time.sleep(sleep_time)
|
||||
|
||||
|
||||
def _merge()
|
||||
"""Stitches images from each module a single one (for each colour)
|
||||
Merges black and colour band for black-white epaper
|
||||
"""
|
||||
|
||||
image = Image.new('RGB',
|
||||
im_location = images
|
||||
# Check if both files exist
|
||||
# Center sub images
|
||||
|
||||
|
||||
for module in self.active_modules:
|
||||
|
||||
im1_name, im2_name = module+'.png', module+'_colour.png'
|
||||
|
||||
# Check if display can only show black-white
|
||||
if self.Settings.supports_colour == False:
|
||||
if exists(im1_name) and exists(im2_name):
|
||||
im1 = Image.open(images+im1_name).convert('RGBA')
|
||||
im2 = Image.open(images+im2_name).convert('RGBA')
|
||||
|
||||
# White to transparent pixels
|
||||
def clear_white(img):
|
||||
"""Replace all white pixels from image with transparent pixels
|
||||
"""
|
||||
x = numpy.asarray(img.convert('RGBA')).copy()
|
||||
x[:, :, 3] = (255 * (x[:, :, :3] != 255).any(axis=2)).astype(numpy.uint8)
|
||||
return Image.fromarray(x)
|
||||
|
||||
# Paste black pixels of im2 on im1
|
||||
im2 = clear_white(im2)
|
||||
im1.paste(im2, (0,0), im2)
|
||||
im1.save(module+'_comb.png', 'PNG')
|
||||
|
||||
# Check if display can support colour
|
||||
elif self.Settings.supports_colour == True:
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user