misc: attempted refactoring of the display support in something less shitty

This commit is contained in:
Simone Margaritelli 2019-10-15 11:50:09 +02:00
parent df33d20cb2
commit 13d68c7c24
30 changed files with 429 additions and 317 deletions

View File

@ -18,7 +18,7 @@ def on_ui_update(ui):
global update_count
update_count += 1
if update_count == OPTIONS['refresh_interval']:
ui._init_display()
ui.init_display()
ui.set('status', "Screen cleaned")
logging.info("Screen refreshing")
update_count = 0

View File

@ -1,13 +1,12 @@
import _thread
from threading import Lock
from PIL import Image
import shutil
import logging
import os
import pwnagotchi, pwnagotchi.plugins as plugins
from pwnagotchi.ui.view import WHITE, View
import pwnagotchi.ui.hw as hw
from pwnagotchi.ui.view import View
from http.server import BaseHTTPRequestHandler, HTTPServer
@ -88,24 +87,15 @@ class VideoHandler(BaseHTTPRequestHandler):
class Display(View):
def __init__(self, config, state={}):
super(Display, self).__init__(config, state)
super(Display, self).__init__(config, hw.display_for(config), state)
self._enabled = config['ui']['display']['enabled']
self._rotation = config['ui']['display']['rotation']
self._video_enabled = config['ui']['display']['video']['enabled']
self._video_port = config['ui']['display']['video']['port']
self._video_address = config['ui']['display']['video']['address']
self._display_type = config['ui']['display']['type']
self._display_color = config['ui']['display']['color']
self._render_cb = None
self._display = None
self._httpd = None
if self._enabled:
self._init_display()
else:
self.on_render(self._on_view_rendered)
logging.warning("display module is disabled")
self.init_display()
if self._video_enabled:
_thread.start_new_thread(self._http_serve, ())
@ -119,149 +109,33 @@ class Display(View):
logging.info("could not get ip of usb0, video server not starting")
def is_inky(self):
return self._display_type in ('inkyphat', 'inky')
return self._implementation.name == 'inky'
def is_papirus(self):
return self._display_type in ('papirus', 'papi')
return self._implementation.name == 'papirus'
def is_waveshare_v1(self):
return self._display_type in ('waveshare_1', 'ws_1', 'waveshare1', 'ws1')
return self._implementation.name == 'waveshare_1'
def is_waveshare_v2(self):
return self._display_type in ('waveshare_2', 'ws_2', 'waveshare2', 'ws2')
return self._implementation.name == 'waveshare_2'
def is_oledhat(self):
return self._display_type in ('oledhat')
return self._implementation.name == 'oledhat'
def is_waveshare_any(self):
return self.is_waveshare_v1() or self.is_waveshare_v2()
def _init_display(self):
if self.is_inky():
logging.info("initializing inky display")
from pwnagotchi.ui.inkyphat.inkyphatfast import InkyPHATFast
self._display = InkyPHATFast(self._display_color)
self._display.set_border(InkyPHATFast.BLACK)
self._render_cb = self._inky_render
elif self.is_papirus():
logging.info("initializing papirus display")
from pwnagotchi.ui.papirus.epd import EPD
os.environ['EPD_SIZE'] = '2.0'
self._display = EPD()
self._display.clear()
self._render_cb = self._papirus_render
elif self.is_waveshare_v1():
if self._display_color == 'black':
logging.info("initializing waveshare v1 display in monochromatic mode")
from pwnagotchi.ui.waveshare.v1.epd2in13 import EPD
self._display = EPD()
self._display.init(self._display.lut_full_update)
self._display.Clear(0xFF)
self._display.init(self._display.lut_partial_update)
self._render_cb = self._waveshare_render
def init_display(self):
if self._enabled:
self._implementation.initialize()
plugins.on('display_setup', self._implementation)
else:
logging.info("initializing waveshare v1 display 3-color mode")
from pwnagotchi.ui.waveshare.v1.epd2in13bc import EPD
self._display = EPD()
self._display.init()
self._display.Clear()
self._render_cb = self._waveshare_bc_render
elif self.is_waveshare_v2():
logging.info("initializing waveshare v2 display")
from pwnagotchi.ui.waveshare.v2.waveshare import EPD
self._display = EPD()
self._display.init(self._display.FULL_UPDATE)
self._display.Clear(WHITE)
self._display.init(self._display.PART_UPDATE)
self._render_cb = self._waveshare_render
elif self.is_oledhat():
logging.info("initializing oledhat display")
from pwnagotchi.ui.waveshare.oledhat.epd import EPD
self._display = EPD()
self._display.init()
self._display.Clear()
self._render_cb = self._oledhat_render
else:
logging.critical("unknown display type %s" % self._display_type)
plugins.on('display_setup', self._display)
logging.warning("display module is disabled")
self.on_render(self._on_view_rendered)
def clear(self):
if self._display is None:
logging.error("no display object created")
elif self.is_inky():
self._display.Clear()
elif self.is_papirus():
self._display.clear()
elif self.is_waveshare_any():
self._display.Clear(WHITE)
elif self.is_oledhat():
self._display.clear()
else:
logging.critical("unknown display type %s" % self._display_type)
def _inky_render(self):
if self._display_color != 'mono':
display_colors = 3
else:
display_colors = 2
img_buffer = self._canvas.convert('RGB').convert('P', palette=1, colors=display_colors)
if self._display_color == 'red':
img_buffer.putpalette([
255, 255, 255, # index 0 is white
0, 0, 0, # index 1 is black
255, 0, 0 # index 2 is red
])
elif self._display_color == 'yellow':
img_buffer.putpalette([
255, 255, 255, # index 0 is white
0, 0, 0, # index 1 is black
255, 255, 0 # index 2 is yellow
])
else:
img_buffer.putpalette([
255, 255, 255, # index 0 is white
0, 0, 0 # index 1 is black
])
self._display.set_image(img_buffer)
try:
self._display.show()
except:
logging.exception("error while rendering on inky")
def _papirus_render(self):
self._display.display(self._canvas)
self._display.partial_update()
def _waveshare_render(self):
buf = self._display.getbuffer(self._canvas)
if self.is_waveshare_v1():
self._display.display(buf)
elif self.is_waveshare_v2():
self._display.displayPartial(buf)
def _oledhat_render(self):
self._display.display(self._canvas)
def _waveshare_bc_render(self):
buf_black = self._display.getbuffer(self._canvas)
# emptyImage = Image.new('1', (self._display.height, self._display.width), 255)
# buf_color = self._display.getbuffer(emptyImage)
# self._display.display(buf_black,buf_color)
# Custom display function that only handles black
# Was included in epd2in13bc.py
self._display.displayBlack(buf_black)
self._implementation.clear()
def image(self):
img = None
@ -271,8 +145,7 @@ class Display(View):
def _on_view_rendered(self, img):
VideoHandler.render(img)
if self._enabled:
self._canvas = (img if self._rotation == 0 else img.rotate(self._rotation))
if self._render_cb is not None:
self._render_cb()
if self._implementation is not None:
self._implementation.render(self._canvas)

View File

@ -0,0 +1,23 @@
from pwnagotchi.ui.hw.inky import Inky
from pwnagotchi.ui.hw.papirus import Papirus
from pwnagotchi.ui.hw.oledhat import OledHat
from pwnagotchi.ui.hw.waveshare1 import WaveshareV1
from pwnagotchi.ui.hw.waveshare2 import WaveshareV2
def display_for(config):
# config has been normalized already in utils.load_config
if config['ui']['display']['type'] == 'inky':
return Inky(config)
elif config['ui']['display']['type'] == 'papirus':
return Papirus(config)
if config['ui']['display']['type'] == 'oledhat':
return OledHat(config)
elif config['ui']['display']['type'] == 'waveshare_1':
return WaveshareV1(config)
elif config['ui']['display']['type'] == 'waveshare_2':
return WaveshareV2(config)

40
pwnagotchi/ui/hw/base.py Normal file
View File

@ -0,0 +1,40 @@
import pwnagotchi.ui.fonts as fonts
class DisplayImpl(object):
def __init__(self, config, name):
self.name = name
self.config = config['ui']['display']
self._layout = {
'width': 0,
'height': 0,
'face': (0, 0),
'name': (0, 0),
'channel': (0, 0),
'aps': (0, 0),
'uptime': (0, 0),
'line1': (0, 0),
'line2': (0, 0),
'friend_face': (0, 0),
'friend_name': (0, 0),
'shakes': (0, 0),
'mode': (0, 0),
# status is special :D
'status': {
'pos': (0, 0),
'font': fonts.Medium,
'max': 20
}
}
def layout(self):
raise NotImplementedError
def initialize(self):
raise NotImplementedError
def render(self, canvas):
raise NotImplementedError
def clear(self):
raise NotImplementedError

72
pwnagotchi/ui/hw/inky.py Normal file
View File

@ -0,0 +1,72 @@
import logging
import pwnagotchi.ui.fonts as fonts
from pwnagotchi.ui.hw.base import DisplayImpl
class Inky(DisplayImpl):
def __init__(self, config):
super(Inky, self).__init__(config, 'inky')
self._display = None
def layout(self):
fonts.setup(10, 8, 10, 28)
self._layout['width'] = 212
self._layout['height'] = 104
self._layout['face'] = (0, 37)
self._layout['name'] = (5, 18)
self._layout['channel'] = (0, 0)
self._layout['aps'] = (25, 0)
self._layout['uptime'] = (147, 0)
self._layout['line1'] = [0, 12, 212, 12]
self._layout['line2'] = [0, 92, 212, 92]
self._layout['friend_face'] = (0, 76)
self._layout['friend_name'] = (40, 78)
self._layout['shakes'] = (0, 93)
self._layout['mode'] = (187, 93)
self._layout['status'] = {
'pos': (102, 18),
'font': fonts.Small,
'max': 20
}
return self._layout
def initialize(self):
logging.info("initializing inky display")
from pwnagotchi.ui.hw.libs.inkyphat.inkyphatfast import InkyPHATFast
self._display = InkyPHATFast(self.config['color'])
self._display.set_border(InkyPHATFast.BLACK)
def render(self, canvas):
if self.config['color'] != 'mono':
display_colors = 3
else:
display_colors = 2
img_buffer = canvas.convert('RGB').convert('P', palette=1, colors=display_colors)
if self.config['color'] == 'red':
img_buffer.putpalette([
255, 255, 255, # index 0 is white
0, 0, 0, # index 1 is black
255, 0, 0 # index 2 is red
])
elif self.config['color'] == 'yellow':
img_buffer.putpalette([
255, 255, 255, # index 0 is white
0, 0, 0, # index 1 is black
255, 255, 0 # index 2 is yellow
])
else:
img_buffer.putpalette([
255, 255, 255, # index 0 is white
0, 0, 0 # index 1 is black
])
self._display.set_image(img_buffer)
try:
self._display.show()
except:
logging.exception("error while rendering on inky")
def clear(self):
self._display.Clear()

View File

@ -15,7 +15,7 @@
from PIL import Image
from PIL import ImageOps
from pwnagotchi.ui.papirus.lm75b import LM75B
from pwnagotchi.ui.hw.libs.papirus import LM75B
import re
import os
import sys

View File

@ -1,7 +1,6 @@
from . import config
import RPi.GPIO as GPIO
import time
import numpy as np
Device_SPI = config.Device_SPI
Device_I2C = config.Device_I2C

View File

@ -1,10 +1,5 @@
from . import SH1106
import time
from . import config
import traceback
from PIL import Image,ImageDraw,ImageFont
# Display resolution
EPD_WIDTH = 64

View File

@ -30,7 +30,6 @@
import logging
from . import epdconfig
import numpy as np
# Display resolution
EPD_WIDTH = 122

View File

@ -27,9 +27,7 @@
# THE SOFTWARE.
#
import logging
from . import epdconfig
from PIL import Image
import RPi.GPIO as GPIO
# import numpy as np

View File

@ -0,0 +1,45 @@
import logging
import pwnagotchi.ui.fonts as fonts
from pwnagotchi.ui.hw.base import DisplayImpl
class OledHat(DisplayImpl):
def __init__(self, config):
super(OledHat, self).__init__(config, 'oledhat')
self._display = None
def layout(self):
fonts.setup(8, 8, 8, 8)
self._layout['width'] = 128
self._layout['height'] = 64
self._layout['face'] = (0, 32)
self._layout['name'] = (0, 10)
self._layout['channel'] = (0, 0)
self._layout['aps'] = (25, 0)
self._layout['uptime'] = (65, 0)
self._layout['line1'] = [0, 9, 128, 9]
self._layout['line2'] = [0, 53, 128, 53]
self._layout['friend_face'] = (0, 41)
self._layout['friend_name'] = (40, 43)
self._layout['shakes'] = (0, 53)
self._layout['mode'] = (103, 10)
self._layout['status'] = {
'pos': (30, 18),
'font': fonts.Small,
'max': 18
}
return self._layout
def initialize(self):
logging.info("initializing oledhat display")
from pwnagotchi.ui.hw.libs.waveshare.oledhat.epd import EPD
self._display = EPD()
self._display.init()
self._display.Clear()
def render(self, canvas):
self._display.display(canvas)
def clear(self):
self._display.clear()

View File

@ -0,0 +1,47 @@
import logging
import os
import pwnagotchi.ui.fonts as fonts
from pwnagotchi.ui.hw.base import DisplayImpl
class Papirus(DisplayImpl):
def __init__(self, config):
super(Papirus, self).__init__(config, 'papirus')
self._display = None
def layout(self):
fonts.setup(10, 8, 10, 23)
self._layout['width'] = 200
self._layout['height'] = 96
self._layout['face'] = (0, 24)
self._layout['name'] = (5, 14)
self._layout['channel'] = (0, 0)
self._layout['aps'] = (25, 0)
self._layout['uptime'] = (135, 0)
self._layout['line1'] = [0, 11, 200, 11]
self._layout['line2'] = [0, 85, 200, 85]
self._layout['friend_face'] = (0, 69)
self._layout['friend_name'] = (40, 71)
self._layout['shakes'] = (0, 86)
self._layout['mode'] = (175, 86)
self._layout['status'] = {
'pos': (85, 14),
'font': fonts.Medium,
'max': 16
}
return self._layout
def initialize(self):
logging.info("initializing papirus display")
from pwnagotchi.ui.hw.libs.papirus.epd import EPD
os.environ['EPD_SIZE'] = '2.0'
self._display = EPD()
self._display.clear()
def render(self, canvas):
self._display.display(canvas)
self._display.partial_update()
def clear(self):
self._display.clear()

View File

@ -0,0 +1,86 @@
import logging
import pwnagotchi.ui.fonts as fonts
from pwnagotchi.ui.hw.base import DisplayImpl
class WaveshareV1(DisplayImpl):
def __init__(self, config):
super(WaveshareV1, self).__init__(config, 'waveshare_1')
self._display = None
def layout(self):
if self.config['color'] == 'black':
fonts.setup(10, 9, 10, 35)
self._layout['width'] = 250
self._layout['height'] = 122
self._layout['face'] = (0, 40)
self._layout['name'] = (5, 20)
self._layout['channel'] = (0, 0)
self._layout['aps'] = (28, 0)
self._layout['uptime'] = (185, 0)
self._layout['line1'] = [0, 14, 250, 14]
self._layout['line2'] = [0, 108, 250, 108]
self._layout['friend_face'] = (0, 92)
self._layout['friend_name'] = (40, 94)
self._layout['shakes'] = (0, 109)
self._layout['mode'] = (225, 109)
self._layout['status'] = {
'pos': (125, 20),
'font': fonts.Medium,
'max': 20
}
else:
fonts.setup(10, 8, 10, 25)
self._layout['width'] = 212
self._layout['height'] = 104
self._layout['face'] = (0, 26)
self._layout['name'] = (5, 15)
self._layout['channel'] = (0, 0)
self._layout['aps'] = (28, 0)
self._layout['status'] = (91, 15)
self._layout['uptime'] = (147, 0)
self._layout['line1'] = [0, 12, 212, 12]
self._layout['line2'] = [0, 92, 212, 92]
self._layout['friend_face'] = (0, 76)
self._layout['friend_name'] = (40, 78)
self._layout['shakes'] = (0, 93)
self._layout['mode'] = (187, 93)
self._layout['status'] = {
'pos': (125, 20),
'font': fonts.Medium,
'max': 14
}
return self._layout
def initialize(self):
if self.config['color'] == 'black':
logging.info("initializing waveshare v1 display in monochromatic mode")
from pwnagotchi.ui.hw.libs.waveshare.v1.epd2in13 import EPD
self._display = EPD()
self._display.init(self._display.lut_full_update)
self._display.Clear(0xFF)
self._display.init(self._display.lut_partial_update)
else:
logging.info("initializing waveshare v1 display 3-color mode")
from pwnagotchi.ui.hw.libs.waveshare.v1.epd2in13bc import EPD
self._display = EPD()
self._display.init()
self._display.Clear()
def render(self, canvas):
if self.config['color'] == 'black':
buf = self._display.getbuffer(canvas)
self._display.display(buf)
else:
buf_black = self._display.getbuffer(canvas)
# emptyImage = Image.new('1', (self._display.height, self._display.width), 255)
# buf_color = self._display.getbuffer(emptyImage)
# self._display.display(buf_black,buf_color)
# Custom display function that only handles black
# Was included in epd2in13bc.py
self._display.displayBlack(buf_black)
def clear(self):
self._display.Clear(0xff)

View File

@ -0,0 +1,69 @@
import logging
import pwnagotchi.ui.fonts as fonts
from pwnagotchi.ui.hw.base import DisplayImpl
class WaveshareV2(DisplayImpl):
def __init__(self, config):
super(WaveshareV2, self).__init__(config, 'waveshare_2')
self._display = None
def layout(self):
if self.config['color'] == 'black':
fonts.setup(10, 9, 10, 35)
self._layout['width'] = 250
self._layout['height'] = 122
self._layout['face'] = (0, 40)
self._layout['name'] = (5, 20)
self._layout['channel'] = (0, 0)
self._layout['aps'] = (28, 0)
self._layout['uptime'] = (185, 0)
self._layout['line1'] = [0, 14, 250, 14]
self._layout['line2'] = [0, 108, 250, 108]
self._layout['friend_face'] = (0, 92)
self._layout['friend_name'] = (40, 94)
self._layout['shakes'] = (0, 109)
self._layout['mode'] = (225, 109)
self._layout['status'] = {
'pos': (125, 20),
'font': fonts.Medium,
'max': 20
}
else:
fonts.setup(10, 8, 10, 25)
self._layout['width'] = 212
self._layout['height'] = 104
self._layout['face'] = (0, 26)
self._layout['name'] = (5, 15)
self._layout['channel'] = (0, 0)
self._layout['aps'] = (28, 0)
self._layout['status'] = (91, 15)
self._layout['uptime'] = (147, 0)
self._layout['line1'] = [0, 12, 212, 12]
self._layout['line2'] = [0, 92, 212, 92]
self._layout['friend_face'] = (0, 76)
self._layout['friend_name'] = (40, 78)
self._layout['shakes'] = (0, 93)
self._layout['mode'] = (187, 93)
self._layout['status'] = {
'pos': (125, 20),
'font': fonts.Medium,
'max': 14
}
return self._layout
def initialize(self):
logging.info("initializing waveshare v2 display")
from pwnagotchi.ui.hw.libs.waveshare.v2.waveshare import EPD
self._display = EPD()
self._display.init(self._display.FULL_UPDATE)
self._display.Clear(0xff)
self._display.init(self._display.PART_UPDATE)
def render(self, canvas):
buf = self._display.getbuffer(canvas)
self._display.displayPartial(buf)
def clear(self):
self._display.Clear(0xff)

View File

@ -1,155 +0,0 @@
import pwnagotchi.ui.fonts as fonts
def inkyphat(config, layout):
fonts.setup(10, 8, 10, 28)
layout['width'] = 212
layout['height'] = 104
layout['face'] = (0, 37)
layout['name'] = (5, 18)
layout['channel'] = (0, 0)
layout['aps'] = (25, 0)
layout['uptime'] = (147, 0)
layout['line1'] = [0, 12, 212, 12]
layout['line2'] = [0, 92, 212, 92]
layout['friend_face'] = (0, 76)
layout['friend_name'] = (40, 78)
layout['shakes'] = (0, 93)
layout['mode'] = (187, 93)
layout['status'] = {
'pos': (102, 18),
'font': fonts.Small,
'max': 20
}
return layout
def papirus(config, layout):
fonts.setup(10, 8, 10, 23)
layout['width'] = 200
layout['height'] = 96
layout['face'] = (0, 24)
layout['name'] = (5, 14)
layout['channel'] = (0, 0)
layout['aps'] = (25, 0)
layout['uptime'] = (135, 0)
layout['line1'] = [0, 11, 200, 11]
layout['line2'] = [0, 85, 200, 85]
layout['friend_face'] = (0, 69)
layout['friend_name'] = (40, 71)
layout['shakes'] = (0, 86)
layout['mode'] = (175, 86)
layout['status'] = {
'pos': (85, 14),
'font': fonts.Medium,
'max': 16
}
return layout
def oledhat(config, layout):
fonts.setup(8, 8, 8, 8)
layout['width'] = 128
layout['height'] = 64
layout['face'] = (0, 32)
layout['name'] = (0, 10)
layout['channel'] = (0, 0)
layout['aps'] = (25, 0)
layout['uptime'] = (65, 0)
layout['line1'] = [0, 9, 128, 9]
layout['line2'] = [0, 53, 128, 53]
layout['friend_face'] = (0, 41)
layout['friend_name'] = (40, 43)
layout['shakes'] = (0, 53)
layout['mode'] = (103, 10)
layout['status'] = {
'pos': (30, 18),
'font': fonts.Small,
'max': 18
}
return layout
def waveshare(config, layout):
if config['ui']['display']['color'] == 'black':
fonts.setup(10, 9, 10, 35)
layout['width'] = 250
layout['height'] = 122
layout['face'] = (0, 40)
layout['name'] = (5, 20)
layout['channel'] = (0, 0)
layout['aps'] = (28, 0)
layout['uptime'] = (layout['width'] - 65, 0)
layout['line1'] = [0, int(layout['height'] * .12), layout['width'], int(layout['height'] * .12)]
layout['line2'] = [0, layout['height'] - int(layout['height'] * .12), layout['width'],
layout['height'] - int(layout['height'] * .12)]
layout['friend_face'] = (0, (layout['height'] * 0.88) - 15)
layout['friend_name'] = (40, (layout['height'] * 0.88) - 13)
layout['shakes'] = (0, layout['height'] - int(layout['height'] * .12) + 1)
layout['mode'] = (layout['width'] - 25, layout['height'] - int(layout['height'] * .12) + 1)
else:
fonts.setup(10, 8, 10, 25)
layout['width'] = 212
layout['height'] = 104
layout['face'] = (0, int(layout['height'] / 4))
layout['name'] = (5, int(layout['height'] * .15))
layout['channel'] = (0, 0)
layout['aps'] = (28, 0)
layout['status'] = (int(layout['width'] / 2) - 15, int(layout['height'] * .15))
layout['uptime'] = (layout['width'] - 65, 0)
layout['line1'] = [0, int(layout['height'] * .12), layout['width'], int(layout['height'] * .12)]
layout['line2'] = [0, layout['height'] - int(layout['height'] * .12), layout['width'],
layout['height'] - int(layout['height'] * .12)]
layout['friend_face'] = (0, (layout['height'] * 0.88) - 15)
layout['friend_name'] = (40, (layout['height'] * 0.88) - 13)
layout['shakes'] = (0, layout['height'] - int(layout['height'] * .12) + 1)
layout['mode'] = (layout['width'] - 25, layout['height'] - int(layout['height'] * .12) + 1)
layout['status'] = {
'pos': (125, 20),
'font': fonts.Medium,
'max': (layout['width'] - 125) // 6
}
return layout
def for_display(config):
layout = {
'width': 0,
'height': 0,
'face': (0, 0),
'name': (0, 0),
'channel': (0, 0),
'aps': (0, 0),
'uptime': (0, 0),
'line1': (0, 0),
'line2': (0, 0),
'friend_face': (0, 0),
'friend_name': (0, 0),
'shakes': (0, 0),
'mode': (0, 0),
# status is special :D
'status': {
'pos': (0, 0),
'font': fonts.Medium,
'max': 20
}
}
if config['ui']['display']['type'] in ('inky', 'inkyphat'):
layout = inkyphat(config, layout)
elif config['ui']['display']['type'] in ('papirus', 'papi'):
layout = papirus(config, layout)
if config['ui']['display']['type'] in ('oledhat'):
layout = oledhat(config, layout)
elif config['ui']['display']['type'] in ('ws_1', 'ws1', 'waveshare_1', 'waveshare1',
'ws_2', 'ws2', 'waveshare_2', 'waveshare2'):
layout = waveshare(config, layout)
return layout

View File

@ -10,7 +10,6 @@ from pwnagotchi.voice import Voice
import pwnagotchi.ui.fonts as fonts
import pwnagotchi.ui.faces as faces
import pwnagotchi.ui.layout as layout
from pwnagotchi.ui.components import *
from pwnagotchi.ui.state import State
@ -20,7 +19,7 @@ ROOT = None
class View(object):
def __init__(self, config, state={}):
def __init__(self, config, impl, state=None):
global ROOT
self._render_cbs = []
@ -29,7 +28,8 @@ class View(object):
self._frozen = False
self._lock = Lock()
self._voice = Voice(lang=config['main']['lang'])
self._layout = layout.for_display(config)
self._implementation = impl
self._layout = impl.layout(config)
self._width = self._layout['width']
self._height = self._layout['height']
self._state = State(state={
@ -70,6 +70,7 @@ class View(object):
font=fonts.Bold, color=BLACK),
})
if state:
for key, value in state.items():
self._state.set(key, value)

View File

@ -56,6 +56,26 @@ def load_config(args):
if user_config:
config = merge_config(user_config, config)
# the very first step is to normalize the display name so we don't need dozens of if/elif around
if config['ui']['display']['type'] in ('inky', 'inkyphat'):
config['ui']['display']['type'] = 'inky'
elif config['ui']['display']['type'] in ('papirus', 'papi'):
config['ui']['display']['type'] = 'papirus'
if config['ui']['display']['type'] in ('oledhat'):
config['ui']['display']['type'] = 'oledhat'
elif config['ui']['display']['type'] in ('ws_1', 'ws1', 'waveshare_1', 'waveshare1'):
config['ui']['display']['type'] = 'waveshare_1'
elif config['ui']['display']['type'] in ('ws_2', 'ws2', 'waveshare_2', 'waveshare2'):
config['ui']['display']['type'] = 'waveshare_2'
else:
print("unsupported display type %s" % config['ui']['display']['type'])
exit(1)
return config