-
-
Notifications
You must be signed in to change notification settings - Fork 345
Expand file tree
/
Copy pathdisplay.py
More file actions
168 lines (146 loc) · 8.1 KB
/
display.py
File metadata and controls
168 lines (146 loc) · 8.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# SPDX-License-Identifier: GPL-3.0-or-later
#
# turing-smart-screen-python - a Python system monitor and library for USB-C displays like Turing Smart Screen or XuanFang
# https://github.com/mathoudebine/turing-smart-screen-python/
#
# Copyright (C) 2021 Matthieu Houdebine (mathoudebine)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from library.config import config
from library.lcd.lcd_comm import Orientation
from library.lcd.lcd_comm_rev_a import LcdCommRevA
from library.lcd.lcd_comm_rev_b import LcdCommRevB
from library.lcd.lcd_comm_rev_c import LcdCommRevC
from library.lcd.lcd_comm_rev_d import LcdCommRevD
from library.lcd.lcd_comm_weact_a import LcdCommWeActA
from library.lcd.lcd_comm_weact_b import LcdCommWeActB
from library.lcd.lcd_simulated import LcdSimulated
from library.log import logger
def _get_full_path(path, name):
if name:
return path + name
return None
def _get_theme_orientation() -> Orientation:
if config.THEME_DATA["display"]["DISPLAY_ORIENTATION"] == 'portrait':
if config.CONFIG_DATA["display"].get("DISPLAY_REVERSE", False):
return Orientation.REVERSE_PORTRAIT
else:
return Orientation.PORTRAIT
elif config.THEME_DATA["display"]["DISPLAY_ORIENTATION"] == 'landscape':
if config.CONFIG_DATA["display"].get("DISPLAY_REVERSE", False):
return Orientation.REVERSE_LANDSCAPE
else:
return Orientation.LANDSCAPE
else:
logger.warning("Orientation '", config.THEME_DATA["display"]["DISPLAY_ORIENTATION"],
"' unknown, using portrait")
return Orientation.PORTRAIT
def _get_theme_size() -> tuple[int, int]:
sizes = {
'0.96"': (80, 160),
'2.1"': (480, 480),
'3.5"': (320, 480),
'5"': (480, 800),
'8.8"': (480, 1920),
}
if config.THEME_DATA["display"].get("DISPLAY_SIZE", '') not in sizes.keys():
logger.warning(
f'Cannot find valid DISPLAY_SIZE property in selected theme {config.CONFIG_DATA["config"]["THEME"]}, defaulting to 3.5"')
return sizes.get(config.THEME_DATA["display"].get("DISPLAY_SIZE", ''), (320, 480))
class Display:
def __init__(self):
self.lcd = None
width, height = _get_theme_size()
if config.CONFIG_DATA["display"]["REVISION"] == "A":
self.lcd = LcdCommRevA(com_port=config.CONFIG_DATA['config']['COM_PORT'],
update_queue=config.update_queue)
elif config.CONFIG_DATA["display"]["REVISION"] == "B":
self.lcd = LcdCommRevB(com_port=config.CONFIG_DATA['config']['COM_PORT'],
update_queue=config.update_queue)
elif config.CONFIG_DATA["display"]["REVISION"] == "C":
# Because of issue with Turing rev. C size auto-detection, manually configure screen width/height from theme
self.lcd = LcdCommRevC(com_port=config.CONFIG_DATA['config']['COM_PORT'],
update_queue=config.update_queue, display_width=width, display_height=height)
elif config.CONFIG_DATA["display"]["REVISION"] == "D":
self.lcd = LcdCommRevD(com_port=config.CONFIG_DATA['config']['COM_PORT'],
update_queue=config.update_queue)
elif config.CONFIG_DATA["display"]["REVISION"] == "WEACT_A":
self.lcd = LcdCommWeActA(com_port=config.CONFIG_DATA['config']['COM_PORT'],
update_queue=config.update_queue)
elif config.CONFIG_DATA["display"]["REVISION"] == "WEACT_B":
self.lcd = LcdCommWeActB(com_port=config.CONFIG_DATA['config']['COM_PORT'],
update_queue=config.update_queue)
elif config.CONFIG_DATA["display"]["REVISION"] == "SIMU":
# Simulated display: always set width/height from theme
self.lcd = LcdSimulated(display_width=width, display_height=height)
else:
logger.error("Unknown display revision '", config.CONFIG_DATA["display"]["REVISION"], "'")
def initialize_display(self):
# Reset screen in case it was in an unstable state (screen is also cleared)
# Can be disabled by config. option. Assume true if key not present in config.yaml
if config.CONFIG_DATA["display"].get("RESET_ON_STARTUP", True):
self.lcd.Reset()
else:
logger.debug("RESET_ON_STARTUP is false: display will not be reset")
# Send initialization commands
self.lcd.InitializeComm()
# Turn on display, set brightness and LEDs for supported HW
self.turn_on()
# Set orientation
self.lcd.SetOrientation(_get_theme_orientation())
def turn_on(self):
# Turn screen on in case it was turned off previously
self.lcd.ScreenOn()
# Set brightness
self.lcd.SetBrightness(config.CONFIG_DATA["display"]["BRIGHTNESS"])
# Set backplate RGB LED color (for supported HW only)
self.lcd.SetBackplateLedColor(config.THEME_DATA['display'].get("DISPLAY_RGB_LED", (255, 255, 255)))
def turn_off(self):
# Turn screen off
self.lcd.ScreenOff()
# Turn off backplate RGB LED
self.lcd.SetBackplateLedColor(led_color=(0, 0, 0))
def display_static_images(self):
if config.THEME_DATA.get('static_images', False):
for image in config.THEME_DATA['static_images']:
logger.debug(f"Drawing Image: {image}")
self.lcd.DisplayBitmap(
bitmap_path=config.THEME_DATA['PATH'] + config.THEME_DATA['static_images'][image].get("PATH"),
x=config.THEME_DATA['static_images'][image].get("X", 0),
y=config.THEME_DATA['static_images'][image].get("Y", 0),
width=config.THEME_DATA['static_images'][image].get("WIDTH", 0),
height=config.THEME_DATA['static_images'][image].get("HEIGHT", 0)
)
def display_static_text(self):
if config.THEME_DATA.get('static_text', False):
for text in config.THEME_DATA['static_text']:
logger.debug(f"Drawing Text: {text}")
self.lcd.DisplayText(
text=config.THEME_DATA['static_text'][text].get("TEXT"),
x=config.THEME_DATA['static_text'][text].get("X", 0),
y=config.THEME_DATA['static_text'][text].get("Y", 0),
width=config.THEME_DATA['static_text'][text].get("WIDTH", 0),
height=config.THEME_DATA['static_text'][text].get("HEIGHT", 0),
font=config.FONTS_DIR + config.THEME_DATA['static_text'][text].get("FONT",
"roboto-mono/RobotoMono-Regular.ttf"),
font_size=config.THEME_DATA['static_text'][text].get("FONT_SIZE", 10),
font_color=config.THEME_DATA['static_text'][text].get("FONT_COLOR", (0, 0, 0)),
background_color=config.THEME_DATA['static_text'][text].get("BACKGROUND_COLOR", (255, 255, 255)),
background_image=_get_full_path(config.THEME_DATA['PATH'],
config.THEME_DATA['static_text'][text].get("BACKGROUND_IMAGE",
None)),
align=config.THEME_DATA['static_text'][text].get("ALIGN", "left"),
anchor=config.THEME_DATA['static_text'][text].get("ANCHOR", "lt"),
)
display = Display()