2020-11-09 17:51:15 +01:00
|
|
|
#!/usr/bin/python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
"""
|
|
|
|
Main class for inkycal Project
|
|
|
|
Copyright by aceisace
|
|
|
|
"""
|
2020-05-26 19:20:18 +02:00
|
|
|
|
2020-11-09 17:51:15 +01:00
|
|
|
from inkycal.display import Display
|
|
|
|
from inkycal.custom import *
|
2020-06-22 15:52:42 +02:00
|
|
|
import os
|
2020-05-26 19:20:18 +02:00
|
|
|
import traceback
|
|
|
|
import logging
|
|
|
|
import arrow
|
|
|
|
import time
|
2020-11-09 17:51:15 +01:00
|
|
|
import json
|
2020-05-26 19:20:18 +02:00
|
|
|
|
|
|
|
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')
|
|
|
|
|
2020-11-09 17:51:15 +01:00
|
|
|
filename = os.path.basename(__file__).split('.py')[0]
|
|
|
|
logger = logging.getLogger(filename)
|
2020-05-29 04:00:39 +02:00
|
|
|
logger.setLevel(level=logging.ERROR)
|
2020-05-26 19:20:18 +02:00
|
|
|
|
2020-11-09 17:51:15 +01:00
|
|
|
|
2020-05-29 04:00:39 +02:00
|
|
|
class Inkycal:
|
2020-07-04 16:21:15 +02:00
|
|
|
"""Inkycal main class"""
|
2020-05-26 19:20:18 +02:00
|
|
|
|
2020-05-29 04:00:39 +02:00
|
|
|
def __init__(self, settings_path, render=True):
|
2020-11-09 17:51:15 +01:00
|
|
|
"""Initialise Inkycal
|
2020-05-26 19:20:18 +02:00
|
|
|
settings_path = str -> location/folder of settings file
|
|
|
|
render = bool -> show something on the ePaper?
|
|
|
|
"""
|
2020-11-09 17:51:15 +01:00
|
|
|
self._release = '2.0.0'
|
2020-05-29 04:00:39 +02:00
|
|
|
|
2020-11-09 17:51:15 +01:00
|
|
|
# Check if render was set correctly
|
|
|
|
if render not in [True, False]:
|
2020-05-26 19:20:18 +02:00
|
|
|
raise Exception('render must be True or False, not "{}"'.format(render))
|
|
|
|
self.render = render
|
|
|
|
|
2020-11-09 17:51:15 +01:00
|
|
|
# load settings file - throw an error if file could not be found
|
|
|
|
try:
|
|
|
|
with open(settings_path) as file:
|
|
|
|
settings = json.load(file)
|
|
|
|
self.settings = settings
|
2020-06-12 18:16:19 +02:00
|
|
|
|
2020-11-09 17:51:15 +01:00
|
|
|
except FileNotFoundError:
|
|
|
|
print('No settings file found in specified location')
|
|
|
|
print('Please double check your path')
|
2020-05-29 04:00:39 +02:00
|
|
|
|
|
|
|
# Option to use epaper image optimisation
|
|
|
|
self.optimize = True
|
|
|
|
|
|
|
|
# Load drivers if image should be rendered
|
|
|
|
if self.render == True:
|
|
|
|
|
2020-11-09 17:51:15 +01:00
|
|
|
# Init Display class with model in settings file
|
2020-05-29 04:00:39 +02:00
|
|
|
from inkycal.display import Display
|
2020-11-09 17:51:15 +01:00
|
|
|
self.Display = Display(settings["model"])
|
2020-05-29 04:00:39 +02:00
|
|
|
|
2020-11-09 17:51:15 +01:00
|
|
|
# check if colours can be rendered
|
|
|
|
self.supports_colour = True if 'colour' in settings['model'] else False
|
2020-06-18 16:24:27 +02:00
|
|
|
|
2020-11-09 17:51:15 +01:00
|
|
|
# init calibration state
|
2020-06-18 16:24:27 +02:00
|
|
|
self._calibration_state = False
|
|
|
|
|
2020-11-09 17:51:15 +01:00
|
|
|
|
|
|
|
|
|
|
|
# WIP
|
|
|
|
for module in settings['modules']:
|
2020-05-26 19:20:18 +02:00
|
|
|
try:
|
2020-11-09 17:51:15 +01:00
|
|
|
loader = f'from inkycal.modules import {module["name"]}'
|
|
|
|
print(loader)
|
|
|
|
conf = module["config"]
|
|
|
|
#size, conf = module_data['size'], module_data['config']
|
|
|
|
setup = f'self.{module} = {module}(size, conf)'
|
2020-05-26 19:20:18 +02:00
|
|
|
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))
|
|
|
|
|
2020-11-09 17:51:15 +01:00
|
|
|
except Exception as e:
|
|
|
|
print(str(e))
|
|
|
|
|
2020-05-26 19:20:18 +02:00
|
|
|
# Give an OK message
|
|
|
|
print('loaded inkycal')
|
|
|
|
|
2020-07-04 16:21:15 +02:00
|
|
|
def countdown(self, interval_mins=None):
|
2020-05-26 19:20:18 +02:00
|
|
|
"""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:
|
2020-11-09 17:51:15 +01:00
|
|
|
interval_mins = self.settings.update_interval
|
2020-05-26 19:20:18 +02:00
|
|
|
|
|
|
|
# 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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-05-29 04:00:39 +02:00
|
|
|
|
2020-06-22 15:52:42 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-11-09 17:51:15 +01:00
|
|
|
if __name__ == '__main__':
|
|
|
|
print('running {0} in standalone/debug mode'.format(filename))
|
2020-06-22 15:52:42 +02:00
|
|
|
|
|
|
|
|