Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display inherits from base display #55

Merged
merged 4 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 2 additions & 20 deletions modules/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,25 +442,7 @@ class Config:
G_FULLSCREEN = False

# display type (overwritten with setting.conf)
G_DISPLAY = "None" # PiTFT, MIP, Papirus, MIP_Sharp

# screen size (need to add when adding new device)
G_AVAILABLE_DISPLAY = {
"None": {"size": (400, 240), "touch": True, "color": True},
"PiTFT": {"size": (320, 240), "touch": True, "color": True},
"MIP": {
"size": (400, 240),
"touch": False,
"color": True,
}, # LPM027M128C, LPM027M128B
"MIP_640": {"size": (640, 480), "touch": False, "color": True}, # LPM044M141A
"MIP_Sharp": {"size": (400, 240), "touch": False, "color": False},
"MIP_Sharp_320": {"size": (320, 240), "touch": False, "color": False},
"Papirus": {"size": (264, 176), "touch": False, "color": False},
"DFRobot_RPi_Display": {"size": (250, 122), "touch": False, "color": False},
}
G_WIDTH = 400
G_HEIGHT = 240
G_DISPLAY = "None" # PiTFT, MIP, MIP_640, Papirus, MIP_Sharp, MIP_Sharp_320, DFRobot_RPi_Display

G_DISPLAY_PARAM = {
"SPI_CLOCK": 2000000,
Expand Down Expand Up @@ -759,7 +741,7 @@ def __init__(self):
def init_loop(self, call_from_gui=False):
if self.G_GUI_MODE == "PyQt":
if call_from_gui:
#asyncio.set_event_loop(self.loop)
# asyncio.set_event_loop(self.loop)
# workaround for latest qasync and older version(~0.24.0)
asyncio.events._set_running_loop(self.loop)
self.start_coroutine()
Expand Down
37 changes: 20 additions & 17 deletions modules/display/dfrobot_rpi_display.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from logger import app_logger
from .display_core import Display

_SENSOR_DISPLAY = False

Expand All @@ -21,29 +22,32 @@
# e-ink Display Module for Raspberry Pi 4B/3B+/Zero W version 1.0


class DFRobotRPiDisplay:
config = None
class DFRobotRPiDisplay(Display):
epaper = None

has_color = False
has_touch = False

size = (250, 122)

def __init__(self, config):
self.config = config

if _SENSOR_DISPLAY:
self.epaper = DFRobot_Epaper_SPI(
RASPBERRY_SPI_BUS,
RASPBERRY_SPI_DEV,
RASPBERRY_PIN_CS,
RASPBERRY_PIN_CD,
RASPBERRY_PIN_BUSY,
)
self.epaper.begin()
self.clear()
super().__init__(config)

self.epaper = DFRobot_Epaper_SPI(
RASPBERRY_SPI_BUS,
RASPBERRY_SPI_DEV,
RASPBERRY_PIN_CS,
RASPBERRY_PIN_CD,
RASPBERRY_PIN_BUSY,
)
self.epaper.begin()
self.clear()

def clear(self):
self.epaper.clear(self.epaper.WHITE)
self.epaper.flush(self.epaper.FULL)

def update(self, im_array):
def update(self, im_array, direct_update=False):
self.epaper.bitmap(
0,
0, # start X and Y
Expand All @@ -56,5 +60,4 @@ def update(self, im_array):
self.epaper.flush(self.epaper.PART)

def quit(self):
if _SENSOR_DISPLAY:
self.clear()
self.clear()
194 changes: 85 additions & 109 deletions modules/display/display_core.py
Copy link
Owner

@hishizuka hishizuka Oct 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If in X environment, send is not necessary. No buffer calculation is required.

# default display (X window)
class Display:
    has_color = True
    has_touch = True
    send = False #not True

or

def init_display(config):
    # default dummy display

    display = Display(config)

    if not config.G_IS_RASPI:
        config.G_DISPLAY = "None"
        (+) display.send = False
        return display

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep my bad.
What about the change to asyncio you introduced?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The corrected code seems to be the old correct order of execution.
In the latest version, the proper code should be reconsidered.

https://github.com/CabbageDevelopment/qasync/blob/master/qasync/__init__.py#L332

Original file line number Diff line number Diff line change
@@ -1,135 +1,111 @@
import os

from logger import app_logger
from ..sensor.sensor import Sensor

DISPLAY = None
DEFAULT_RESOLUTION = (400, 240)

SUPPORTED_DISPLAYS = {
# display name, resolution if different from its class default
"None": None, # DEFAULT_RESOLUTION
"PiTFT": None,
"MIP": None, # LPM027M128C, LPM027M128B
"MIP_640": (640, 480), # LPM044M141A
"MIP_Sharp": None,
"MIP_Sharp_320": (320, 240),
"Papirus": None,
"DFRobot_RPi_Display": None,
}

class Display(Sensor):
sensor = {}
elements = ()
display = None
send_display = False

def sensor_init(self):
self.detect_display()
self.set_resolution()
# default display (X window)
class Display:
has_color = True
has_touch = True
send = True

self.reset()
def __init__(self, config):
self.config = config

if not self.config.G_IS_RASPI:
self.config.G_DISPLAY = "None"
return
@property
def resolution(self):
return getattr(self, "size", DEFAULT_RESOLUTION)

if self.config.G_DISPLAY == "PiTFT":
from .pitft_28_r import PiTFT28r
def start_coroutine(self):
pass

self.display = PiTFT28r(self.config)
elif self.config.G_DISPLAY in ("MIP", "MIP_640"):
from .mip_display import MipDisplay
def quit(self):
pass

self.display = MipDisplay(self.config)
self.send_display = True
elif self.config.G_DISPLAY in ("MIP_Sharp", "MIP_Sharp_320"):
from .mip_sharp_display import MipSharpDisplay
def update(self, buf, direct_update):
pass

self.display = MipSharpDisplay(self.config)
self.send_display = True
elif self.config.G_DISPLAY == "Papirus":
from .papirus_display import PapirusDisplay
def screen_flash_long(self):
pass

self.display = PapirusDisplay(self.config)
self.send_display = True
elif self.config.G_DISPLAY == "DFRobot_RPi_Display":
from .dfrobot_rpi_display import DFRobotRPiDisplay
def screen_flash_short(self):
pass

self.display = DFRobotRPiDisplay(self.config)
self.send_display = True
def change_brightness(self):
pass

def detect_display(self):
hatdir = "/proc/device-tree/hat"
product_file = hatdir + "/product"
vendor_file = hatdir + "/vendor"

if (os.path.exists(product_file)) and (os.path.exists(vendor_file)):
with open(hatdir + "/product") as f:
p = f.read()
with open(hatdir + "/vendor") as f:
v = f.read()
app_logger.info(f"{product_file}: {p}")
app_logger.info(f"{vendor_file}: {v}")
def detect_display():
hatdir = "/proc/device-tree/hat"
product_file = f"{hatdir}/product"
vendor_file = f"{hatdir}/vendor"
if os.path.exists(product_file) and os.path.exists(vendor_file):
with open(product_file) as f:
p = f.read()
with open(vendor_file) as f:
v = f.read()
app_logger.info(f"{product_file}: {p}")
app_logger.info(f"{vendor_file}: {v}")
# set display
if p.find("Adafruit PiTFT HAT - 2.4 inch Resistive Touch") == 0:
return "PiTFT"
elif (p.find("PaPiRus ePaper HAT") == 0) and (v.find("Pi Supply") == 0):
return "Papirus"
return None

# set display
if p.find("Adafruit PiTFT HAT - 2.4 inch Resistive Touch") == 0:
self.config.G_DISPLAY = "PiTFT"
elif (p.find("PaPiRus ePaper HAT") == 0) and (v.find("Pi Supply") == 0):
self.config.G_DISPLAY = "Papirus"

def set_resolution(self):
for key in self.config.G_AVAILABLE_DISPLAY.keys():
if self.config.G_DISPLAY == key:
self.config.G_WIDTH = self.config.G_AVAILABLE_DISPLAY[key]["size"][0]
self.config.G_HEIGHT = self.config.G_AVAILABLE_DISPLAY[key]["size"][1]
break
def init_display(config):
# default dummy display

def has_touch(self):
return self.config.G_AVAILABLE_DISPLAY[self.config.G_DISPLAY]["touch"]
display = Display(config)

def has_color(self):
return self.config.G_AVAILABLE_DISPLAY[self.config.G_DISPLAY]["color"]
if not config.G_IS_RASPI:
config.G_DISPLAY = "None"
return display

def start_coroutine(self):
if self.config.G_DISPLAY in ("MIP", "MIP_640", "MIP_Sharp", "MIP_Sharp_320"):
self.display.start_coroutine()
auto_detect = detect_display()

def quit(self):
if not self.config.G_IS_RASPI:
return
if self.config.G_DISPLAY == "PiTFT":
pass
elif (
self.config.G_DISPLAY in ("MIP", "MIP_640", "MIP_Sharp", "MIP_Sharp_320")
and self.send_display
):
self.display.quit()
elif self.config.G_DISPLAY in ("Papirus", "DFRobot_RPi_Display"):
self.display.quit()
if auto_detect is not None:
config.G_DISPLAY = auto_detect

def update(self, buf, direct_update):
if not self.config.G_IS_RASPI or not self.send_display:
return

if direct_update and self.config.G_DISPLAY in (
"MIP",
"MIP_Sharp",
"MIP_Sharp_320",
):
self.display.update(buf, direct_update)
elif self.config.G_DISPLAY in ("MIP", "MIP_640", "MIP_Sharp", "MIP_Sharp_320"):
self.display.update(buf, direct_update=False)
elif self.config.G_DISPLAY in ("Papirus", "DFRobot_RPi_Display"):
self.display.update(buf)
if config.G_DISPLAY == "PiTFT":
from .pitft_28_r import _SENSOR_DISPLAY, PiTFT28r

def screen_flash_long(self):
if (
self.config.G_DISPLAY in ("MIP", "MIP_640", "MIP_Sharp", "MIP_Sharp_320")
and self.send_display
):
self.display.inversion(0.8)
# self.display.blink(1.0)
if _SENSOR_DISPLAY:
display = PiTFT28r(config)
elif config.G_DISPLAY in ("MIP", "MIP_640"):
from .mip_display import _SENSOR_DISPLAY, MipDisplay

def screen_flash_short(self):
if (
self.config.G_DISPLAY in ("MIP", "MIP_640", "MIP_Sharp", "MIP_Sharp_320")
and self.send_display
):
self.display.inversion(0.3)

def brightness_control(self):
if not self.config.G_IS_RASPI:
return
if self.config.G_DISPLAY == "PiTFT":
self.display.change_brightness()
elif self.config.G_DISPLAY in ("MIP", "MIP_640") and self.send_display:
self.display.change_brightness()
if _SENSOR_DISPLAY:
display = MipDisplay(config, SUPPORTED_DISPLAYS[config.G_DISPLAY])
elif config.G_DISPLAY in ("MIP_Sharp", "MIP_Sharp_320"):
from .mip_sharp_display import _SENSOR_DISPLAY, MipSharpDisplay

if _SENSOR_DISPLAY:
display = MipSharpDisplay(config, SUPPORTED_DISPLAYS[config.G_DISPLAY])
elif config.G_DISPLAY == "Papirus":
from .papirus_display import _SENSOR_DISPLAY, PapirusDisplay

if _SENSOR_DISPLAY:
display = PapirusDisplay(config)
elif config.G_DISPLAY == "DFRobot_RPi_Display":
from .dfrobot_rpi_display import _SENSOR_DISPLAY, DFRobotRPiDisplay

if _SENSOR_DISPLAY:
display = DFRobotRPiDisplay(config)

return display
Loading