misc: attempted refactoring of the display support in something less shitty
This commit is contained in:
parent
df33d20cb2
commit
13d68c7c24
@ -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
|
||||
|
@ -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)
|
||||
|
23
pwnagotchi/ui/hw/__init__.py
Normal file
23
pwnagotchi/ui/hw/__init__.py
Normal 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
40
pwnagotchi/ui/hw/base.py
Normal 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
72
pwnagotchi/ui/hw/inky.py
Normal 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()
|
@ -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
|
@ -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
|
@ -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
|
@ -30,7 +30,6 @@
|
||||
|
||||
import logging
|
||||
from . import epdconfig
|
||||
import numpy as np
|
||||
|
||||
# Display resolution
|
||||
EPD_WIDTH = 122
|
@ -27,9 +27,7 @@
|
||||
# THE SOFTWARE.
|
||||
#
|
||||
|
||||
import logging
|
||||
from . import epdconfig
|
||||
from PIL import Image
|
||||
import RPi.GPIO as GPIO
|
||||
# import numpy as np
|
||||
|
0
pwnagotchi/ui/hw/libs/waveshare/v2/__init__.py
Normal file
0
pwnagotchi/ui/hw/libs/waveshare/v2/__init__.py
Normal file
45
pwnagotchi/ui/hw/oledhat.py
Normal file
45
pwnagotchi/ui/hw/oledhat.py
Normal 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()
|
47
pwnagotchi/ui/hw/papirus.py
Normal file
47
pwnagotchi/ui/hw/papirus.py
Normal 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()
|
86
pwnagotchi/ui/hw/waveshare1.py
Normal file
86
pwnagotchi/ui/hw/waveshare1.py
Normal 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)
|
69
pwnagotchi/ui/hw/waveshare2.py
Normal file
69
pwnagotchi/ui/hw/waveshare2.py
Normal 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)
|
@ -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
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user