diff --git a/README.md b/README.md
index ea26342d..2a2a6aad 100644
--- a/README.md
+++ b/README.md
@@ -32,6 +32,10 @@ Supported operating systems : macOS, Windows, Linux (incl. Raspberry Pi), basica
|
|
|
| Unknown manufacturer, visually similar to Turing 3.5" / 5". Original software is `UsbPCMonitor.exe` | Front panel has an engraved inscription "奇叶智显" Qiye Zhixian (Qiye Smart Display) |
+| ✅ WeAct Studio Display FS V1 0.96" | ✅ WeAct Studio Display FS V1 3.5" |
+|---------------------------------------------------------------|--------------------------------------------------------------|
+|
|
|
+
❌ Not (yet) supported / not tested smart screen models
diff --git a/config.yaml b/config.yaml
index 23814969..bacc6001 100644
--- a/config.yaml
+++ b/config.yaml
@@ -52,10 +52,12 @@ config:
display:
# Display revision:
- # - A for Turing 3.5" and UsbPCMonitor 3.5"/5"
- # - B for Xuanfang 3.5" (inc. flagship)
- # - C for Turing 2.1"/5"/8.8"
- # - D for Kipye Qiye Smart Display 3.5"
+ # - A for Turing 3.5" and UsbPCMonitor 3.5"/5"
+ # - B for Xuanfang 3.5" (inc. flagship)
+ # - C for Turing 2.1"/5"/8.8"
+ # - D for Kipye Qiye Smart Display 3.5"
+ # - WEACT_A for WeAct Studio Display FS V1 3.5"
+ # - WEACT_B for WeAct Studio Display FS V1 0.96"
# - SIMU for simulated display (image written in screencap.png). Width & height will be detected from the theme
# To identify your smart screen: https://github.com/mathoudebine/turing-smart-screen-python/wiki/Hardware-revisions
REVISION: A
diff --git a/configure.py b/configure.py
index 989388fd..d4c318f1 100755
--- a/configure.py
+++ b/configure.py
@@ -60,14 +60,16 @@
USBPCMONITOR_MODEL = "UsbPCMonitor"
XUANFANG_MODEL = "XuanFang rev. B & flagship"
KIPYE_MODEL = "Kipye Qiye Smart Display"
+WEACT_MODEL = "WeAct Studio Display FS V1"
SIMULATED_MODEL = "Simulated screen"
SIZE_3_5_INCH = "3.5\""
SIZE_5_INCH = "5\""
SIZE_8_8_INCH = "8.8\""
SIZE_2_1_INCH = "2.1\""
+SIZE_0_96_INCH = "0.96\""
-size_list = (SIZE_2_1_INCH, SIZE_3_5_INCH, SIZE_5_INCH, SIZE_8_8_INCH)
+size_list = (SIZE_0_96_INCH, SIZE_2_1_INCH, SIZE_3_5_INCH, SIZE_5_INCH, SIZE_8_8_INCH)
# Maps between config.yaml values and GUI description
revision_and_size_to_model_map = {
@@ -78,6 +80,9 @@
('C', SIZE_5_INCH): TURING_MODEL,
('C', SIZE_8_8_INCH): TURING_MODEL,
('D', SIZE_3_5_INCH): KIPYE_MODEL,
+ ('WEACT_A', SIZE_3_5_INCH): WEACT_MODEL,
+ ('WEACT_B', SIZE_0_96_INCH): WEACT_MODEL,
+ ('SIMU', SIZE_0_96_INCH): SIMULATED_MODEL,
('SIMU', SIZE_2_1_INCH): SIMULATED_MODEL,
('SIMU', SIZE_3_5_INCH): SIMULATED_MODEL,
('SIMU', SIZE_5_INCH): SIMULATED_MODEL,
@@ -92,6 +97,9 @@
(TURING_MODEL, SIZE_5_INCH): 'C',
(TURING_MODEL, SIZE_8_8_INCH): 'C',
(KIPYE_MODEL, SIZE_3_5_INCH): 'D',
+ (WEACT_MODEL, SIZE_3_5_INCH): 'WEACT_A',
+ (WEACT_MODEL, SIZE_0_96_INCH): 'WEACT_B',
+ (SIMULATED_MODEL, SIZE_0_96_INCH): 'SIMU',
(SIMULATED_MODEL, SIZE_2_1_INCH): 'SIMU',
(SIMULATED_MODEL, SIZE_3_5_INCH): 'SIMU',
(SIMULATED_MODEL, SIZE_5_INCH): 'SIMU',
diff --git a/library/display.py b/library/display.py
index 7aa187c9..d4f21009 100644
--- a/library/display.py
+++ b/library/display.py
@@ -24,6 +24,8 @@
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
@@ -53,6 +55,8 @@ def _get_theme_orientation() -> Orientation:
def _get_theme_size() -> tuple[int, int]:
+ if config.THEME_DATA["display"].get("DISPLAY_SIZE", '') == '0.96"':
+ return 80, 160
if config.THEME_DATA["display"].get("DISPLAY_SIZE", '') == '2.1"':
return 480, 480
elif config.THEME_DATA["display"].get("DISPLAY_SIZE", '') == '3.5"':
@@ -84,6 +88,12 @@ def __init__(self):
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)
diff --git a/library/lcd/lcd_comm.py b/library/lcd/lcd_comm.py
index 5487706c..4e2714fe 100644
--- a/library/lcd/lcd_comm.py
+++ b/library/lcd/lcd_comm.py
@@ -124,6 +124,10 @@ def serial_read(self, size: int) -> bytes:
assert self.lcd_serial is not None
return self.lcd_serial.read(size)
+ def serial_readall(self) -> bytes:
+ assert self.lcd_serial is not None
+ return self.lcd_serial.readall()
+
def serial_flush_input(self):
if self.lcd_serial is not None:
self.lcd_serial.reset_input_buffer()
@@ -223,6 +227,12 @@ def DisplayPILImage(
def DisplayBitmap(self, bitmap_path: str, x: int = 0, y: int = 0, width: int = 0, height: int = 0):
image = self.open_image(bitmap_path)
+
+ # Resize the picture if custom width/height provided
+ if width != 0 and height != 0:
+ if width != image.size[0] or height != image.size[1]:
+ image = image.resize((width, height))
+
self.DisplayPILImage(image, x, y, width, height)
def DisplayText(
diff --git a/library/lcd/lcd_comm_rev_a.py b/library/lcd/lcd_comm_rev_a.py
index fd34badf..520b8364 100644
--- a/library/lcd/lcd_comm_rev_a.py
+++ b/library/lcd/lcd_comm_rev_a.py
@@ -190,11 +190,6 @@ def DisplayPILImage(
if not image_width:
image_width = image.size[0]
- assert x <= width, 'Image X coordinate must be <= display width'
- assert y <= height, 'Image Y coordinate must be <= display height'
- assert image_height > 0, 'Image height must be > 0'
- assert image_width > 0, 'Image width must be > 0'
-
# If our image size + the (x, y) position offsets are bigger than
# our display, reduce the image size to fit our screen
if x + image_width > width:
@@ -205,6 +200,11 @@ def DisplayPILImage(
if image_width != image.size[0] or image_height != image.size[1]:
image = image.crop((0, 0, image_width, image_height))
+ assert x <= width, 'Image X coordinate must be <= display width'
+ assert y <= height, 'Image Y coordinate must be <= display height'
+ assert image_height > 0, 'Image height must be > 0'
+ assert image_width > 0, 'Image width must be > 0'
+
(x0, y0) = (x, y)
(x1, y1) = (x + image_width - 1, y + image_height - 1)
diff --git a/library/lcd/lcd_comm_weact_a.py b/library/lcd/lcd_comm_weact_a.py
new file mode 100644
index 00000000..1f76484d
--- /dev/null
+++ b/library/lcd/lcd_comm_weact_a.py
@@ -0,0 +1,276 @@
+# Copyright (C) 2024-2024 WeAct Studio
+# Imported from https://github.com/WeActStudio/WeActStudio.SystemMonitor
+
+import struct
+
+from serial.tools.list_ports import comports
+
+from library.lcd.lcd_comm import *
+from library.log import logger
+from library.lcd import serialize
+#import fastlz
+
+class Command(IntEnum):
+ CMD_WHO_AM_I = 0x81 # Establish communication before driving the screen
+ CMD_SET_ORIENTATION = 0x02 # Sets the screen orientation
+ CMD_SET_BRIGHTNESS = 0x03 # Sets the screen brightness
+ CMD_FULL = 0x04 # Displays an image on the screen
+ CMD_SET_BITMAP = 0x05 # Displays an image on the screen
+ CMD_SET_BITMAP_WITH_FASTLZ = 0x15
+ CMD_ENABLE_HUMITURE_REPORT = 0x06
+ CMD_FREE = 0x07
+ CMD_SYSTEM_VERSION = 0x42
+ CMD_END = 0x0A # Displays an image on the screen
+ CMD_READ = 0x80
+
+
+# This class is for WeAct Studio Display FS V1 3.5"
+class LcdCommWeActA(LcdComm):
+ def __init__(
+ self,
+ com_port: str = "AUTO",
+ display_width: int = 320,
+ display_height: int = 480,
+ update_queue: queue.Queue = None,
+ ):
+ LcdComm.__init__(self, com_port, display_width, display_height, update_queue)
+ self.brightness = 0
+ self.temperature = 0
+ self.humidness = 0
+ self.support_fastlz = False
+ self.openSerial()
+
+
+ def __del__(self):
+ self.closeSerial()
+
+ @staticmethod
+ def auto_detect_com_port():
+ com_ports = comports()
+
+ for com_port in com_ports:
+ if com_port.vid == 0x1a86 and com_port.pid == 0xfe0c:
+ return com_port.device
+ if type(com_port.serial_number) == str:
+ if com_port.serial_number.startswith("AB"):
+ return com_port.device
+
+ return None
+
+ def Send_Bitmap_xy_Command(self, xs, ys, xe, ye, bypass_queue: bool = False):
+ byteBuffer = bytearray(10)
+ byteBuffer[0] = Command.CMD_SET_BITMAP
+ byteBuffer[1] = xs & 0xFF
+ byteBuffer[2] = xs >> 8 & 0xFF
+ byteBuffer[3] = ys & 0xFF
+ byteBuffer[4] = ys >> 8 & 0xFF
+ byteBuffer[5] = xe & 0xFF
+ byteBuffer[6] = xe >> 8 & 0xFF
+ byteBuffer[7] = ye & 0xFF
+ byteBuffer[8] = ye >> 8 & 0xFF
+ byteBuffer[9] = Command.CMD_END
+
+ # If no queue for async requests, or if asked explicitly to do the request sequentially: do request now
+ if not self.update_queue or bypass_queue:
+ self.WriteData(byteBuffer)
+ else:
+ # Lock queue mutex then queue the request
+ with self.update_queue_mutex:
+ self.update_queue.put((self.WriteData, [byteBuffer]))
+
+ def SendCommand(self, byteBuffer, bypass_queue: bool = False):
+ # If no queue for async requests, or if asked explicitly to do the request sequentially: do request now
+ if not self.update_queue or bypass_queue:
+ self.WriteData(byteBuffer)
+ else:
+ # Lock queue mutex then queue the request
+ with self.update_queue_mutex:
+ self.update_queue.put((self.WriteData, [byteBuffer]))
+
+ def InitializeComm(self,use_compress:int = 0):
+ byteBuffer = bytearray(2)
+ self.serial_readall()
+ byteBuffer[0] = Command.CMD_SYSTEM_VERSION | Command.CMD_READ
+ byteBuffer[1] = Command.CMD_END
+ self.WriteData(byteBuffer)
+ response = self.serial_read(19)
+ self.serial_flush_input()
+ if response and len(response) == 19:
+ version_str = response[1:9].decode('ascii').strip()
+ logger.info(f"Device version: {version_str}")
+ # if version_str.startswith("V"):
+ # if version_str == "V1.0.0.0":
+ # self.support_fastlz = False
+ # logger.info("Device does not support fastlz compression.")
+ # else:
+ # logger.info("Device supports fastlz compression.")
+ # if use_compress:
+ # self.support_fastlz = True
+ # else:
+ # self.support_fastlz = False
+ # logger.info("User disabled fastlz compression.")
+ # else:
+ # self.support_fastlz = False
+ # logger.info("Device does not support fastlz compression.")
+ else:
+ logger.info("Get version failed")
+ pass
+
+ def Reset(self):
+ pass
+
+ def Clear(self):
+ self.Full((0,0,0))
+
+ def Full(self,color: Tuple[int, int, int] = (0, 0, 0)):
+ R = color[0] >> 3
+ G = color[1] >> 2
+ B = color[2] >> 3
+ # Color information is 0bRRRRRGGGGGGBBBBB
+ # Encode in Little-Endian
+ rgb = (R << 11) | (G << 5) | B
+ line = struct.pack("> 8) & 0xff
+ byteBuffer[7] = (ye-1) & 0xff
+ byteBuffer[8] = (ye >> 8) & 0xff
+ byteBuffer[9] = line[0]
+ byteBuffer[10] = line[1]
+ byteBuffer[11] = Command.CMD_END
+ self.SendCommand(byteBuffer)
+
+ def ScreenOff(self):
+ self.SetBrightness(0)
+ self.SetSensorReportTime(0)
+ self.Free()
+
+ def ScreenOn(self):
+ self.SetBrightness(self.brightness)
+
+ def SetBrightness(self, level: int = 0):
+ assert 0 <= level <= 100, "Brightness level must be [0-100]"
+ converted_level = int((level / 100) * 255)
+ brightness_ms = 1000
+ byteBuffer = bytearray(5)
+ byteBuffer[0] = Command.CMD_SET_BRIGHTNESS
+ byteBuffer[1] = converted_level & 0xFF
+ byteBuffer[2] = brightness_ms & 0xFF
+ byteBuffer[3] = brightness_ms >> 8 & 0xFF
+ byteBuffer[4] = Command.CMD_END
+ self.SendCommand(byteBuffer)
+ self.brightness = level
+
+ def SetOrientation(self, orientation: Orientation = Orientation.PORTRAIT):
+ self.orientation = orientation
+ byteBuffer = bytearray(3)
+ byteBuffer[0] = Command.CMD_SET_ORIENTATION
+ byteBuffer[1] = self.orientation
+ byteBuffer[2] = Command.CMD_END
+ self.SendCommand(byteBuffer)
+
+ def SetSensorReportTime(self, time_ms: int):
+ if time_ms > 0xFFFF or (time_ms < 500 and time_ms != 0):
+ return False
+ byteBuffer = bytearray(4)
+ byteBuffer[0] = Command.CMD_ENABLE_HUMITURE_REPORT
+ byteBuffer[1] = time_ms & 0xFF
+ byteBuffer[2] = time_ms >> 8 & 0xFF
+ byteBuffer[3] = Command.CMD_END
+ self.SendCommand(byteBuffer)
+
+ def Free(self):
+ byteBuffer = bytearray(2)
+ byteBuffer[0] = Command.CMD_FREE
+ byteBuffer[1] = Command.CMD_END
+ self.SendCommand(byteBuffer)
+
+ def HandleSensorReport(self):
+ if self.lcd_serial.in_waiting > 0:
+ cmd = self.ReadData(1)
+ if (
+ cmd != None
+ and cmd[0] == Command.CMD_ENABLE_HUMITURE_REPORT | Command.CMD_READ
+ ):
+ data = self.ReadData(5)
+ if data != None and len(data) == 5 and data[4] == Command.CMD_END:
+ unpack = struct.unpack(" self.get_height():
+ image_height = self.get_height()
+ if image.size[0] > self.get_width():
+ image_width = self.get_width()
+
+ assert x <= self.get_width(), f"Display Image X {x} coordinate must be <= display width {self.get_width()}"
+ assert y <= self.get_height(), f"Display Image Y {y} coordinate must be <= display height {self.get_height()}"
+ assert image_height > 0, "Image height must be > 0"
+ assert image_width > 0, "Image width must be > 0"
+ assert x + image_width <= self.get_width(), f'Display Bitmap width+x exceeds display width {self.get_width()}'
+ assert y + image_height <= self.get_height(), f'Display Bitmap height+y exceeds display height {self.get_height()}'
+
+ (x0, y0) = (x, y)
+ (x1, y1) = (x + image_width - 1, y + image_height - 1)
+
+ byteBuffer = bytearray(10)
+ byteBuffer[0] = Command.CMD_SET_BITMAP
+ byteBuffer[1] = x0 & 0xFF
+ byteBuffer[2] = x0 >> 8 & 0xFF
+ byteBuffer[3] = y0 & 0xFF
+ byteBuffer[4] = y0 >> 8 & 0xFF
+ byteBuffer[5] = x1 & 0xFF
+ byteBuffer[6] = x1 >> 8 & 0xFF
+ byteBuffer[7] = y1 & 0xFF
+ byteBuffer[8] = y1 >> 8 & 0xFF
+ byteBuffer[9] = Command.CMD_END
+
+ line_to_send_size = self.get_width() * 4
+
+ rgb565le = serialize.image_to_RGB565(image,'little')
+
+ # if self.support_fastlz:
+ # chunk_size = line_to_send_size
+ # # Lock queue mutex then queue all the requests for the image data
+ # with self.update_queue_mutex:
+ # byteBuffer[0] = Command.CMD_SET_BITMAP_WITH_FASTLZ
+ # self.SendLine(byteBuffer)
+ # # declare the chunk size
+ # for i in range(0, len(rgb565le), chunk_size):
+ # chunk = rgb565le[i:i+chunk_size]
+ # compressed_chunk = fastlz.compress(chunk)
+ # chunk_with_header = struct.pack("> 8 & 0xFF
+ byteBuffer[3] = ys & 0xFF
+ byteBuffer[4] = ys >> 8 & 0xFF
+ byteBuffer[5] = xe & 0xFF
+ byteBuffer[6] = xe >> 8 & 0xFF
+ byteBuffer[7] = ye & 0xFF
+ byteBuffer[8] = ye >> 8 & 0xFF
+ byteBuffer[9] = Command.CMD_END
+
+ # If no queue for async requests, or if asked explicitly to do the request sequentially: do request now
+ if not self.update_queue or bypass_queue:
+ self.WriteData(byteBuffer)
+ else:
+ # Lock queue mutex then queue the request
+ with self.update_queue_mutex:
+ self.update_queue.put((self.WriteData, [byteBuffer]))
+
+ def SendCommand(self, byteBuffer, bypass_queue: bool = False):
+ # If no queue for async requests, or if asked explicitly to do the request sequentially: do request now
+ if not self.update_queue or bypass_queue:
+ self.WriteData(byteBuffer)
+ else:
+ # Lock queue mutex then queue the request
+ with self.update_queue_mutex:
+ self.update_queue.put((self.WriteData, [byteBuffer]))
+
+ def InitializeComm(self,use_compress:int = 0):
+ byteBuffer = bytearray(2)
+ self.serial_readall()
+ byteBuffer[0] = Command.CMD_SYSTEM_VERSION | Command.CMD_READ
+ byteBuffer[1] = Command.CMD_END
+ self.WriteData(byteBuffer)
+ response = self.serial_read(19)
+ self.serial_flush_input()
+ if response and len(response) == 19:
+ version_str = response[1:9].decode('ascii').strip()
+ logger.info(f"Device version: {version_str}")
+ # logger.info("Device supports fastlz compression.")
+ # if use_compress:
+ # self.support_fastlz = True
+ # else:
+ # self.support_fastlz = False
+ # logger.info("User disabled fastlz compression.")
+ else:
+ # self.support_fastlz = False
+ logger.info("Get version failed")
+ pass
+
+ def Reset(self):
+ pass
+
+ def Clear(self):
+ self.Full((0,0,0))
+
+ def Full(self,color: Tuple[int, int, int] = (0, 0, 0)):
+ R = color[0] >> 3
+ G = color[1] >> 2
+ B = color[2] >> 3
+ # Color information is 0bRRRRRGGGGGGBBBBB
+ # Encode in Little-Endian
+ rgb = (R << 11) | (G << 5) | B
+ line = struct.pack("> 8) & 0xff
+ byteBuffer[7] = (ye-1) & 0xff
+ byteBuffer[8] = (ye >> 8) & 0xff
+ byteBuffer[9] = line[0]
+ byteBuffer[10] = line[1]
+ byteBuffer[11] = Command.CMD_END
+ self.SendCommand(byteBuffer)
+
+ def ScreenOff(self):
+ self.SetBrightness(0)
+ # self.SetSensorReportTime(0)
+ self.Free()
+
+ def ScreenOn(self):
+ self.SetBrightness(self.brightness)
+
+ def SetBrightness(self, level: int = 0):
+ assert 0 <= level <= 100, "Brightness level must be [0-100]"
+ converted_level = int((level / 100) * 255)
+ brightness_ms = 1000
+ byteBuffer = bytearray(5)
+ byteBuffer[0] = Command.CMD_SET_BRIGHTNESS
+ byteBuffer[1] = converted_level & 0xFF
+ byteBuffer[2] = brightness_ms & 0xFF
+ byteBuffer[3] = brightness_ms >> 8 & 0xFF
+ byteBuffer[4] = Command.CMD_END
+ self.SendCommand(byteBuffer)
+ self.brightness = level
+
+ def SetOrientation(self, orientation: Orientation = Orientation.PORTRAIT):
+ self.orientation = orientation
+ byteBuffer = bytearray(3)
+ byteBuffer[0] = Command.CMD_SET_ORIENTATION
+ byteBuffer[1] = self.orientation
+ byteBuffer[2] = Command.CMD_END
+ self.SendCommand(byteBuffer)
+
+ def Free(self):
+ byteBuffer = bytearray(2)
+ byteBuffer[0] = Command.CMD_FREE
+ byteBuffer[1] = Command.CMD_END
+ self.SendCommand(byteBuffer)
+
+ def DisplayPILImage(
+ self,
+ image: Image.Image,
+ x: int = 0,
+ y: int = 0,
+ image_width: int = 0,
+ image_height: int = 0,
+ ):
+ # print(f'image.size: {image.size} x: {x} y: {y}')
+
+ # If the image height/width isn't provided, use the native image size
+ if not image_height:
+ image_height = image.size[1]
+ if not image_width:
+ image_width = image.size[0]
+
+ # If our image is bigger than our display, resize it to fit our screen
+ if image.size[1] > self.get_height():
+ image_height = self.get_height()
+ if image.size[0] > self.get_width():
+ image_width = self.get_width()
+
+ assert x >= 0, f"Display Image X {x} coordinate must be >= 0"
+ assert y >= 0, f"Display Image Y {y} coordinate must be >= 0"
+ assert x <= self.get_width(), f"Display Image X {x} coordinate must be <= display width {self.get_width()}"
+ assert y <= self.get_height(), f"Display Image Y {y} coordinate must be <= display height {self.get_height()}"
+ assert image_height > 0, "Image height must be > 0"
+ assert image_width > 0, "Image width must be > 0"
+ assert x + image_width <= self.get_width(), f'Display Bitmap width+x exceeds display width {self.get_width()}'
+ assert y + image_height <= self.get_height(), f'Display Bitmap height+y exceeds display height {self.get_height()}'
+
+ (x0, y0) = (x, y)
+ (x1, y1) = (x + image_width - 1, y + image_height - 1)
+
+ byteBuffer = bytearray(10)
+ byteBuffer[0] = Command.CMD_SET_BITMAP
+ byteBuffer[1] = x0 & 0xFF
+ byteBuffer[2] = x0 >> 8 & 0xFF
+ byteBuffer[3] = y0 & 0xFF
+ byteBuffer[4] = y0 >> 8 & 0xFF
+ byteBuffer[5] = x1 & 0xFF
+ byteBuffer[6] = x1 >> 8 & 0xFF
+ byteBuffer[7] = y1 & 0xFF
+ byteBuffer[8] = y1 >> 8 & 0xFF
+ byteBuffer[9] = Command.CMD_END
+
+ line_to_send_size = self.get_width() * 4
+
+ rgb565le = serialize.image_to_RGB565(image,'little')
+
+ # if self.support_fastlz:
+ # chunk_size = line_to_send_size
+ # # Lock queue mutex then queue all the requests for the image data
+ # with self.update_queue_mutex:
+ # byteBuffer[0] = Command.CMD_SET_BITMAP_WITH_FASTLZ
+ # self.SendLine(byteBuffer)
+ # # declare the chunk size
+ # for i in range(0, len(rgb565le), chunk_size):
+ # chunk = rgb565le[i:i+chunk_size]
+ # compressed_chunk = fastlz.compress(chunk)
+ # chunk_with_header = struct.pack(" self.get_height():
image_height = self.get_height()
if image.size[0] > self.get_width():
image_width = self.get_width()
+ if image_width != image.size[0] or image_height != image.size[1]:
+ image = image.crop((0, 0, image_width, image_height))
+
assert x <= self.get_width(), 'Image X coordinate must be <= display width'
assert y <= self.get_height(), 'Image Y coordinate must be <= display height'
assert image_height > 0, 'Image height must be > 0'
diff --git a/res/docs/weact_0.96.jpg b/res/docs/weact_0.96.jpg
new file mode 100644
index 00000000..6425ac44
Binary files /dev/null and b/res/docs/weact_0.96.jpg differ
diff --git a/res/docs/weact_3.5.png b/res/docs/weact_3.5.png
new file mode 100644
index 00000000..fb94d112
Binary files /dev/null and b/res/docs/weact_3.5.png differ
diff --git a/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_1.92.ttf b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_1.92.ttf
new file mode 100644
index 00000000..2ba681a8
Binary files /dev/null and b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_1.92.ttf differ
diff --git a/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_1.92_preview.png b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_1.92_preview.png
new file mode 100644
index 00000000..3403b7c6
Binary files /dev/null and b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_1.92_preview.png differ
diff --git a/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_3D.ttf b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_3D.ttf
new file mode 100644
index 00000000..8bd57a09
Binary files /dev/null and b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_3D.ttf differ
diff --git a/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_3D_preview.png b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_3D_preview.png
new file mode 100644
index 00000000..10247fae
Binary files /dev/null and b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_3D_preview.png differ
diff --git a/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Blur.ttf b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Blur.ttf
new file mode 100644
index 00000000..8f668423
Binary files /dev/null and b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Blur.ttf differ
diff --git a/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Blur_preview.png b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Blur_preview.png
new file mode 100644
index 00000000..25a80adc
Binary files /dev/null and b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Blur_preview.png differ
diff --git a/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Bold_1.92.ttf b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Bold_1.92.ttf
new file mode 100644
index 00000000..34721706
Binary files /dev/null and b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Bold_1.92.ttf differ
diff --git a/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Bold_1.92_preview.png b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Bold_1.92_preview.png
new file mode 100644
index 00000000..30147ef4
Binary files /dev/null and b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Bold_1.92_preview.png differ
diff --git a/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Circle_Dot.ttf b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Circle_Dot.ttf
new file mode 100644
index 00000000..97582b74
Binary files /dev/null and b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Circle_Dot.ttf differ
diff --git a/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Circle_Dot_preview.png b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Circle_Dot_preview.png
new file mode 100644
index 00000000..b583abe5
Binary files /dev/null and b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Circle_Dot_preview.png differ
diff --git a/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Gradient.ttf b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Gradient.ttf
new file mode 100644
index 00000000..a4994636
Binary files /dev/null and b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Gradient.ttf differ
diff --git a/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Gradient_preview.png b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Gradient_preview.png
new file mode 100644
index 00000000..31fe8875
Binary files /dev/null and b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Gradient_preview.png differ
diff --git a/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Square_Dot.ttf b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Square_Dot.ttf
new file mode 100644
index 00000000..d878fe22
Binary files /dev/null and b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Square_Dot.ttf differ
diff --git a/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Square_Dot_preview.png b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Square_Dot_preview.png
new file mode 100644
index 00000000..d7427844
Binary files /dev/null and b/res/fonts/BoutiqueBitmap9x9/BoutiqueBitmap9x9_Square_Dot_preview.png differ
diff --git a/res/fonts/Cubic_11/Cubic_11.ttf b/res/fonts/Cubic_11/Cubic_11.ttf
new file mode 100644
index 00000000..08d18287
Binary files /dev/null and b/res/fonts/Cubic_11/Cubic_11.ttf differ
diff --git a/res/fonts/Cubic_11/Cubic_11_preview.png b/res/fonts/Cubic_11/Cubic_11_preview.png
new file mode 100644
index 00000000..fc223877
Binary files /dev/null and b/res/fonts/Cubic_11/Cubic_11_preview.png differ
diff --git a/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Bold.otf b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Bold.otf
new file mode 100644
index 00000000..9c13cf95
Binary files /dev/null and b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Bold.otf differ
diff --git a/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Bold_preview.png b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Bold_preview.png
new file mode 100644
index 00000000..b33b3758
Binary files /dev/null and b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Bold_preview.png differ
diff --git a/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Book.otf b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Book.otf
new file mode 100644
index 00000000..52a778d4
Binary files /dev/null and b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Book.otf differ
diff --git a/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Book_preview.png b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Book_preview.png
new file mode 100644
index 00000000..175a505b
Binary files /dev/null and b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Book_preview.png differ
diff --git a/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-ExtraBold.otf b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-ExtraBold.otf
new file mode 100644
index 00000000..4142caac
Binary files /dev/null and b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-ExtraBold.otf differ
diff --git a/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-ExtraBold_preview.png b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-ExtraBold_preview.png
new file mode 100644
index 00000000..1878bc26
Binary files /dev/null and b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-ExtraBold_preview.png differ
diff --git a/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-ExtraLight.otf b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-ExtraLight.otf
new file mode 100644
index 00000000..a6b9ad1b
Binary files /dev/null and b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-ExtraLight.otf differ
diff --git a/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-ExtraLight_preview.png b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-ExtraLight_preview.png
new file mode 100644
index 00000000..7cef60fb
Binary files /dev/null and b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-ExtraLight_preview.png differ
diff --git a/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Light.otf b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Light.otf
new file mode 100644
index 00000000..0d75d83b
Binary files /dev/null and b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Light.otf differ
diff --git a/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Light_preview.png b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Light_preview.png
new file mode 100644
index 00000000..12092c76
Binary files /dev/null and b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Light_preview.png differ
diff --git a/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Medium.otf b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Medium.otf
new file mode 100644
index 00000000..9243908f
Binary files /dev/null and b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Medium.otf differ
diff --git a/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Medium_preview.png b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Medium_preview.png
new file mode 100644
index 00000000..8a4e6373
Binary files /dev/null and b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Medium_preview.png differ
diff --git a/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Regular.otf b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Regular.otf
new file mode 100644
index 00000000..db7fa498
Binary files /dev/null and b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Regular.otf differ
diff --git a/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Regular_preview.png b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Regular_preview.png
new file mode 100644
index 00000000..5d0eb9e6
Binary files /dev/null and b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Regular_preview.png differ
diff --git a/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Thin.otf b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Thin.otf
new file mode 100644
index 00000000..54e95546
Binary files /dev/null and b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Thin.otf differ
diff --git a/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Thin_preview.png b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Thin_preview.png
new file mode 100644
index 00000000..d83615da
Binary files /dev/null and b/res/fonts/GlowSansSC-Compressed/GlowSansSC-Compressed-Thin_preview.png differ
diff --git a/res/fonts/SourceHanSansCN/SourceHanSansCN-Bold.otf b/res/fonts/SourceHanSansCN/SourceHanSansCN-Bold.otf
new file mode 100644
index 00000000..8e1e8694
Binary files /dev/null and b/res/fonts/SourceHanSansCN/SourceHanSansCN-Bold.otf differ
diff --git a/res/fonts/SourceHanSansCN/SourceHanSansCN-Bold_preview.png b/res/fonts/SourceHanSansCN/SourceHanSansCN-Bold_preview.png
new file mode 100644
index 00000000..f7d9974a
Binary files /dev/null and b/res/fonts/SourceHanSansCN/SourceHanSansCN-Bold_preview.png differ
diff --git a/res/fonts/SourceHanSansCN/SourceHanSansCN-ExtraLight.otf b/res/fonts/SourceHanSansCN/SourceHanSansCN-ExtraLight.otf
new file mode 100644
index 00000000..eafebeee
Binary files /dev/null and b/res/fonts/SourceHanSansCN/SourceHanSansCN-ExtraLight.otf differ
diff --git a/res/fonts/SourceHanSansCN/SourceHanSansCN-ExtraLight_preview.png b/res/fonts/SourceHanSansCN/SourceHanSansCN-ExtraLight_preview.png
new file mode 100644
index 00000000..1686fa6e
Binary files /dev/null and b/res/fonts/SourceHanSansCN/SourceHanSansCN-ExtraLight_preview.png differ
diff --git a/res/fonts/SourceHanSansCN/SourceHanSansCN-Heavy.otf b/res/fonts/SourceHanSansCN/SourceHanSansCN-Heavy.otf
new file mode 100644
index 00000000..14c160b7
Binary files /dev/null and b/res/fonts/SourceHanSansCN/SourceHanSansCN-Heavy.otf differ
diff --git a/res/fonts/SourceHanSansCN/SourceHanSansCN-Heavy_preview.png b/res/fonts/SourceHanSansCN/SourceHanSansCN-Heavy_preview.png
new file mode 100644
index 00000000..6c20a907
Binary files /dev/null and b/res/fonts/SourceHanSansCN/SourceHanSansCN-Heavy_preview.png differ
diff --git a/res/fonts/SourceHanSansCN/SourceHanSansCN-Light.otf b/res/fonts/SourceHanSansCN/SourceHanSansCN-Light.otf
new file mode 100644
index 00000000..9185e573
Binary files /dev/null and b/res/fonts/SourceHanSansCN/SourceHanSansCN-Light.otf differ
diff --git a/res/fonts/SourceHanSansCN/SourceHanSansCN-Light_preview.png b/res/fonts/SourceHanSansCN/SourceHanSansCN-Light_preview.png
new file mode 100644
index 00000000..2e840580
Binary files /dev/null and b/res/fonts/SourceHanSansCN/SourceHanSansCN-Light_preview.png differ
diff --git a/res/fonts/SourceHanSansCN/SourceHanSansCN-Medium.otf b/res/fonts/SourceHanSansCN/SourceHanSansCN-Medium.otf
new file mode 100644
index 00000000..630d5467
Binary files /dev/null and b/res/fonts/SourceHanSansCN/SourceHanSansCN-Medium.otf differ
diff --git a/res/fonts/SourceHanSansCN/SourceHanSansCN-Medium_preview.png b/res/fonts/SourceHanSansCN/SourceHanSansCN-Medium_preview.png
new file mode 100644
index 00000000..ce98ab88
Binary files /dev/null and b/res/fonts/SourceHanSansCN/SourceHanSansCN-Medium_preview.png differ
diff --git a/res/fonts/SourceHanSansCN/SourceHanSansCN-Normal.otf b/res/fonts/SourceHanSansCN/SourceHanSansCN-Normal.otf
new file mode 100644
index 00000000..abd36cef
Binary files /dev/null and b/res/fonts/SourceHanSansCN/SourceHanSansCN-Normal.otf differ
diff --git a/res/fonts/SourceHanSansCN/SourceHanSansCN-Normal_preview.png b/res/fonts/SourceHanSansCN/SourceHanSansCN-Normal_preview.png
new file mode 100644
index 00000000..afd16eb8
Binary files /dev/null and b/res/fonts/SourceHanSansCN/SourceHanSansCN-Normal_preview.png differ
diff --git a/res/fonts/SourceHanSansCN/SourceHanSansCN-Regular.otf b/res/fonts/SourceHanSansCN/SourceHanSansCN-Regular.otf
new file mode 100644
index 00000000..c13789be
Binary files /dev/null and b/res/fonts/SourceHanSansCN/SourceHanSansCN-Regular.otf differ
diff --git a/res/fonts/SourceHanSansCN/SourceHanSansCN-Regular_preview.png b/res/fonts/SourceHanSansCN/SourceHanSansCN-Regular_preview.png
new file mode 100644
index 00000000..43ce2123
Binary files /dev/null and b/res/fonts/SourceHanSansCN/SourceHanSansCN-Regular_preview.png differ
diff --git a/res/fonts/digital/DIGITAL-7.TTF b/res/fonts/digital/DIGITAL-7.TTF
new file mode 100644
index 00000000..a481b97b
Binary files /dev/null and b/res/fonts/digital/DIGITAL-7.TTF differ
diff --git a/res/fonts/digital/DIGITAL-7_preview.png b/res/fonts/digital/DIGITAL-7_preview.png
new file mode 100644
index 00000000..b0c30e6b
Binary files /dev/null and b/res/fonts/digital/DIGITAL-7_preview.png differ
diff --git a/res/fonts/font-preview.py b/res/fonts/font-preview.py
index 72584453..096b7ac0 100644
--- a/res/fonts/font-preview.py
+++ b/res/fonts/font-preview.py
@@ -66,6 +66,6 @@ def generate_preview(font_dir: str, font_filename: str, text: str, font_size: in
if os.path.isdir(font_dir):
for font in os.listdir(font_dir):
font_file = os.path.join(font_dir, font)
- if os.path.isfile(font_file) and (font_file.endswith(".ttf") or font_file.endswith(".otf")):
+ if os.path.isfile(font_file) and (font_file.endswith(".ttf") or font_file.endswith(".otf") or font_file.endswith(".TTF") or font_file.endswith(".OTF")):
print(f"Found font {dir}/{font}")
generate_preview(font_dir, font, "40%", font_size=60)
diff --git a/res/fonts/fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf b/res/fonts/fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
new file mode 100644
index 00000000..303f5b77
Binary files /dev/null and b/res/fonts/fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf differ
diff --git a/res/fonts/fusion-pixel/fusion-pixel-10px-monospaced-zh_hans_preview.png b/res/fonts/fusion-pixel/fusion-pixel-10px-monospaced-zh_hans_preview.png
new file mode 100644
index 00000000..2bf947e8
Binary files /dev/null and b/res/fonts/fusion-pixel/fusion-pixel-10px-monospaced-zh_hans_preview.png differ
diff --git a/res/fonts/fusion-pixel/fusion-pixel-12px-monospaced-zh_hans.otf b/res/fonts/fusion-pixel/fusion-pixel-12px-monospaced-zh_hans.otf
new file mode 100644
index 00000000..400f8368
Binary files /dev/null and b/res/fonts/fusion-pixel/fusion-pixel-12px-monospaced-zh_hans.otf differ
diff --git a/res/fonts/fusion-pixel/fusion-pixel-12px-monospaced-zh_hans_preview.png b/res/fonts/fusion-pixel/fusion-pixel-12px-monospaced-zh_hans_preview.png
new file mode 100644
index 00000000..f1bbbe4b
Binary files /dev/null and b/res/fonts/fusion-pixel/fusion-pixel-12px-monospaced-zh_hans_preview.png differ
diff --git a/res/fonts/fusion-pixel/fusion-pixel-8px-monospaced-zh_hans.otf b/res/fonts/fusion-pixel/fusion-pixel-8px-monospaced-zh_hans.otf
new file mode 100644
index 00000000..5f78eaa2
Binary files /dev/null and b/res/fonts/fusion-pixel/fusion-pixel-8px-monospaced-zh_hans.otf differ
diff --git a/res/fonts/fusion-pixel/fusion-pixel-8px-monospaced-zh_hans_preview.png b/res/fonts/fusion-pixel/fusion-pixel-8px-monospaced-zh_hans_preview.png
new file mode 100644
index 00000000..5f35d0e4
Binary files /dev/null and b/res/fonts/fusion-pixel/fusion-pixel-8px-monospaced-zh_hans_preview.png differ
diff --git a/res/fonts/geforce/GeForce-Bold_preview.png b/res/fonts/geforce/GeForce-Bold_preview.png
index 73d15903..aceb390a 100644
Binary files a/res/fonts/geforce/GeForce-Bold_preview.png and b/res/fonts/geforce/GeForce-Bold_preview.png differ
diff --git a/res/fonts/misaki/misaki_gothic.ttf b/res/fonts/misaki/misaki_gothic.ttf
new file mode 100644
index 00000000..51d1cc75
Binary files /dev/null and b/res/fonts/misaki/misaki_gothic.ttf differ
diff --git a/res/fonts/misaki/misaki_gothic_2nd.ttf b/res/fonts/misaki/misaki_gothic_2nd.ttf
new file mode 100644
index 00000000..95fe5d33
Binary files /dev/null and b/res/fonts/misaki/misaki_gothic_2nd.ttf differ
diff --git a/res/fonts/misaki/misaki_gothic_2nd_preview.png b/res/fonts/misaki/misaki_gothic_2nd_preview.png
new file mode 100644
index 00000000..7f80bc82
Binary files /dev/null and b/res/fonts/misaki/misaki_gothic_2nd_preview.png differ
diff --git a/res/fonts/misaki/misaki_gothic_preview.png b/res/fonts/misaki/misaki_gothic_preview.png
new file mode 100644
index 00000000..a1e43963
Binary files /dev/null and b/res/fonts/misaki/misaki_gothic_preview.png differ
diff --git a/res/fonts/misaki/misaki_mincho.ttf b/res/fonts/misaki/misaki_mincho.ttf
new file mode 100644
index 00000000..fb03f836
Binary files /dev/null and b/res/fonts/misaki/misaki_mincho.ttf differ
diff --git a/res/fonts/misaki/misaki_mincho_preview.png b/res/fonts/misaki/misaki_mincho_preview.png
new file mode 100644
index 00000000..a1e43963
Binary files /dev/null and b/res/fonts/misaki/misaki_mincho_preview.png differ
diff --git a/res/fonts/racespace/RACESPACEREGULAR-Extended_preview.png b/res/fonts/racespace/RACESPACEREGULAR-Extended_preview.png
new file mode 100644
index 00000000..36962a34
Binary files /dev/null and b/res/fonts/racespace/RACESPACEREGULAR-Extended_preview.png differ
diff --git a/res/fonts/racespace/RACESPACESTRIPE-Extended_preview.png b/res/fonts/racespace/RACESPACESTRIPE-Extended_preview.png
new file mode 100644
index 00000000..4d0f9859
Binary files /dev/null and b/res/fonts/racespace/RACESPACESTRIPE-Extended_preview.png differ
diff --git a/res/fonts/roboto-mono/RobotoMono-BoldItalic_preview.png b/res/fonts/roboto-mono/RobotoMono-BoldItalic_preview.png
index 8cc420f4..bae54bd9 100644
Binary files a/res/fonts/roboto-mono/RobotoMono-BoldItalic_preview.png and b/res/fonts/roboto-mono/RobotoMono-BoldItalic_preview.png differ
diff --git a/res/fonts/roboto-mono/RobotoMono-ExtraLightItalic_preview.png b/res/fonts/roboto-mono/RobotoMono-ExtraLightItalic_preview.png
index e623660f..4744e1c9 100644
Binary files a/res/fonts/roboto-mono/RobotoMono-ExtraLightItalic_preview.png and b/res/fonts/roboto-mono/RobotoMono-ExtraLightItalic_preview.png differ
diff --git a/res/fonts/roboto-mono/RobotoMono-Italic_preview.png b/res/fonts/roboto-mono/RobotoMono-Italic_preview.png
index 5475a5c0..3e2763f6 100644
Binary files a/res/fonts/roboto-mono/RobotoMono-Italic_preview.png and b/res/fonts/roboto-mono/RobotoMono-Italic_preview.png differ
diff --git a/res/fonts/roboto-mono/RobotoMono-LightItalic_preview.png b/res/fonts/roboto-mono/RobotoMono-LightItalic_preview.png
index 52f0e047..2c789485 100644
Binary files a/res/fonts/roboto-mono/RobotoMono-LightItalic_preview.png and b/res/fonts/roboto-mono/RobotoMono-LightItalic_preview.png differ
diff --git a/res/fonts/roboto-mono/RobotoMono-MediumItalic_preview.png b/res/fonts/roboto-mono/RobotoMono-MediumItalic_preview.png
index d313abbb..0a9a6b49 100644
Binary files a/res/fonts/roboto-mono/RobotoMono-MediumItalic_preview.png and b/res/fonts/roboto-mono/RobotoMono-MediumItalic_preview.png differ
diff --git a/res/fonts/roboto-mono/RobotoMono-SemiBoldItalic_preview.png b/res/fonts/roboto-mono/RobotoMono-SemiBoldItalic_preview.png
index aed3e0eb..28fa4f09 100644
Binary files a/res/fonts/roboto-mono/RobotoMono-SemiBoldItalic_preview.png and b/res/fonts/roboto-mono/RobotoMono-SemiBoldItalic_preview.png differ
diff --git a/res/fonts/roboto-mono/RobotoMono-ThinItalic_preview.png b/res/fonts/roboto-mono/RobotoMono-ThinItalic_preview.png
index 3882ba33..aa7780db 100644
Binary files a/res/fonts/roboto-mono/RobotoMono-ThinItalic_preview.png and b/res/fonts/roboto-mono/RobotoMono-ThinItalic_preview.png differ
diff --git a/res/fonts/roboto/Roboto-Black_preview.png b/res/fonts/roboto/Roboto-Black_preview.png
index fb888918..d8d5be0e 100644
Binary files a/res/fonts/roboto/Roboto-Black_preview.png and b/res/fonts/roboto/Roboto-Black_preview.png differ
diff --git a/res/fonts/roboto/Roboto-BoldItalic_preview.png b/res/fonts/roboto/Roboto-BoldItalic_preview.png
index dd2f9027..02ebc2da 100644
Binary files a/res/fonts/roboto/Roboto-BoldItalic_preview.png and b/res/fonts/roboto/Roboto-BoldItalic_preview.png differ
diff --git a/res/fonts/roboto/Roboto-Bold_preview.png b/res/fonts/roboto/Roboto-Bold_preview.png
index 39db27a4..14febc66 100644
Binary files a/res/fonts/roboto/Roboto-Bold_preview.png and b/res/fonts/roboto/Roboto-Bold_preview.png differ
diff --git a/res/fonts/roboto/Roboto-LightItalic_preview.png b/res/fonts/roboto/Roboto-LightItalic_preview.png
index cb1e9bfb..5cac20a1 100644
Binary files a/res/fonts/roboto/Roboto-LightItalic_preview.png and b/res/fonts/roboto/Roboto-LightItalic_preview.png differ
diff --git a/res/fonts/roboto/Roboto-Light_preview.png b/res/fonts/roboto/Roboto-Light_preview.png
index b6bc711d..916f3e81 100644
Binary files a/res/fonts/roboto/Roboto-Light_preview.png and b/res/fonts/roboto/Roboto-Light_preview.png differ
diff --git a/res/fonts/roboto/Roboto-MediumItalic_preview.png b/res/fonts/roboto/Roboto-MediumItalic_preview.png
index 3e0806e2..9be71fd9 100644
Binary files a/res/fonts/roboto/Roboto-MediumItalic_preview.png and b/res/fonts/roboto/Roboto-MediumItalic_preview.png differ
diff --git a/res/fonts/roboto/Roboto-Regular_preview.png b/res/fonts/roboto/Roboto-Regular_preview.png
index f68ea5ea..57c16123 100644
Binary files a/res/fonts/roboto/Roboto-Regular_preview.png and b/res/fonts/roboto/Roboto-Regular_preview.png differ
diff --git a/res/fonts/roboto/Roboto-Thin_preview.png b/res/fonts/roboto/Roboto-Thin_preview.png
index 6fff3225..f5324f69 100644
Binary files a/res/fonts/roboto/Roboto-Thin_preview.png and b/res/fonts/roboto/Roboto-Thin_preview.png differ
diff --git a/res/themes/Digital_CPU_0.96Inch/background.png b/res/themes/Digital_CPU_0.96Inch/background.png
new file mode 100644
index 00000000..17bc983f
Binary files /dev/null and b/res/themes/Digital_CPU_0.96Inch/background.png differ
diff --git a/res/themes/Digital_CPU_0.96Inch/preview.png b/res/themes/Digital_CPU_0.96Inch/preview.png
new file mode 100644
index 00000000..67f7c291
Binary files /dev/null and b/res/themes/Digital_CPU_0.96Inch/preview.png differ
diff --git a/res/themes/Digital_CPU_0.96Inch/theme.yaml b/res/themes/Digital_CPU_0.96Inch/theme.yaml
new file mode 100644
index 00000000..8de5a74a
--- /dev/null
+++ b/res/themes/Digital_CPU_0.96Inch/theme.yaml
@@ -0,0 +1,95 @@
+# Copyright (C) 2024-2024 WeAct Studio
+# Imported from https://github.com/WeActStudio/WeActStudio.SystemMonitor
+author: '@WeActStudio'
+display:
+ DISPLAY_SIZE: 0.96"
+ DISPLAY_ORIENTATION: landscape
+ DISPLAY_RGB_LED: 85, 85, 85
+
+static_images:
+ background:
+ PATH: background.png
+ X: 0
+ Y: 0
+ WIDTH: 160
+ HEIGHT: 80
+
+static_text:
+ LOAD:
+ TEXT: CPU LOAD
+ X: 85
+ Y: 0
+ WIDTH: 75
+ HEIGHT: 0
+ FONT: digital/DIGITAL-7.TTF
+ FONT_SIZE: 20
+ FONT_COLOR: 20, 240, 116
+ ALIGN: center
+ ANCHOR: lt
+ ROTATION: 0
+ BACKGROUND_IMAGE: background.png
+ TEMP:
+ TEXT: CPU TEMP
+ X: 0
+ Y: 0
+ FONT: digital/DIGITAL-7.TTF
+ FONT_SIZE: 20
+ BACKGROUND_IMAGE: background.png
+ ALIGN: center
+ ANCHOR: lt
+ FONT_COLOR: 248, 195, 34
+ WIDTH: 75
+ HEIGHT: 0
+STATS:
+ CPU:
+ PERCENTAGE:
+ # In seconds. Longer intervals cause this to refresh more slowly.
+ # Setting to lower values will display near real time data,
+ # but may cause significant CPU usage or the display not to update properly
+ INTERVAL: 1
+ TEXT:
+ SHOW: true
+ SHOW_UNIT: false
+ UNIT_ML: false
+ MIN_SIZE: 0
+ X: 150
+ Y: 40
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 0 # Uncomment to force a static width
+ HEIGHT: 0 # Uncomment to force static height
+ FONT: digital/DIGITAL-7.TTF
+ FONT_SIZE: 55
+ FONT_COLOR: 20, 240, 116
+ BACKGROUND_IMAGE: background.png
+ ALIGN: right # left / center / right
+ ANCHOR: rm # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
+ ROTATION: 0
+ TEMPERATURE:
+ # In seconds. Longer intervals cause this to refresh more slowly.
+ # Setting to lower values will display near real time data,
+ # but may cause significant CPU usage or the display not to update properly
+ INTERVAL: 5
+ TEXT:
+ SHOW: true
+ SHOW_UNIT: false
+ UNIT_ML: false
+ MIN_SIZE: 2
+ X: 60
+ Y: 40
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 0 # Uncomment to force a static width
+ HEIGHT: 0 # Uncomment to force static height
+ FONT: digital/DIGITAL-7.TTF
+ FONT_SIZE: 55
+ FONT_COLOR: 248, 195, 34
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ ALIGN: right # left / center / right
+ ANCHOR: rm # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
+ ROTATION: 0
diff --git a/res/themes/Example_0.96Inch_1/Photos/flower/002-lavender.png b/res/themes/Example_0.96Inch_1/Photos/flower/002-lavender.png
new file mode 100644
index 00000000..1f228fef
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/flower/002-lavender.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/flower/003-dahlia.png b/res/themes/Example_0.96Inch_1/Photos/flower/003-dahlia.png
new file mode 100644
index 00000000..f78e0134
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/flower/003-dahlia.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/flower/004-sunflower.png b/res/themes/Example_0.96Inch_1/Photos/flower/004-sunflower.png
new file mode 100644
index 00000000..c5872d53
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/flower/004-sunflower.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/flower/017-bluebell.png b/res/themes/Example_0.96Inch_1/Photos/flower/017-bluebell.png
new file mode 100644
index 00000000..7c959d8b
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/flower/017-bluebell.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/flower/022-lily.png b/res/themes/Example_0.96Inch_1/Photos/flower/022-lily.png
new file mode 100644
index 00000000..bd305ffd
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/flower/022-lily.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/flower/027-geranium.png b/res/themes/Example_0.96Inch_1/Photos/flower/027-geranium.png
new file mode 100644
index 00000000..36cc8d8f
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/flower/027-geranium.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/flower/029-arugula.png b/res/themes/Example_0.96Inch_1/Photos/flower/029-arugula.png
new file mode 100644
index 00000000..3c2a0613
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/flower/029-arugula.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/flower/030-cactus.png b/res/themes/Example_0.96Inch_1/Photos/flower/030-cactus.png
new file mode 100644
index 00000000..b53c6ba3
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/flower/030-cactus.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/flower/035-garlic mustard.png b/res/themes/Example_0.96Inch_1/Photos/flower/035-garlic mustard.png
new file mode 100644
index 00000000..569582b3
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/flower/035-garlic mustard.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/flower/042-pea.png b/res/themes/Example_0.96Inch_1/Photos/flower/042-pea.png
new file mode 100644
index 00000000..b2cd0f65
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/flower/042-pea.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/flower/046-amaryllis.png b/res/themes/Example_0.96Inch_1/Photos/flower/046-amaryllis.png
new file mode 100644
index 00000000..2ffacc5a
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/flower/046-amaryllis.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/flower/048-anthurium.png b/res/themes/Example_0.96Inch_1/Photos/flower/048-anthurium.png
new file mode 100644
index 00000000..0696a468
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/flower/048-anthurium.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/flower/049-freesia.png b/res/themes/Example_0.96Inch_1/Photos/flower/049-freesia.png
new file mode 100644
index 00000000..670cee6a
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/flower/049-freesia.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/logo.png b/res/themes/Example_0.96Inch_1/Photos/logo.png
new file mode 100644
index 00000000..5ad86465
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/logo.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/logo/003-pictures.png b/res/themes/Example_0.96Inch_1/Photos/logo/003-pictures.png
new file mode 100644
index 00000000..b7e76943
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/logo/003-pictures.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/logo/004-palm tree.png b/res/themes/Example_0.96Inch_1/Photos/logo/004-palm tree.png
new file mode 100644
index 00000000..9e4bdcf6
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/logo/004-palm tree.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/logo/005-sand bucket.png b/res/themes/Example_0.96Inch_1/Photos/logo/005-sand bucket.png
new file mode 100644
index 00000000..08ae694c
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/logo/005-sand bucket.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/logo/007-ice cream.png b/res/themes/Example_0.96Inch_1/Photos/logo/007-ice cream.png
new file mode 100644
index 00000000..7a076bce
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/logo/007-ice cream.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/logo/008-sun.png b/res/themes/Example_0.96Inch_1/Photos/logo/008-sun.png
new file mode 100644
index 00000000..df2274fe
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/logo/008-sun.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/logo/013-sun umbrella.png b/res/themes/Example_0.96Inch_1/Photos/logo/013-sun umbrella.png
new file mode 100644
index 00000000..54e9175b
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/logo/013-sun umbrella.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/logo/020-swimsuit.png b/res/themes/Example_0.96Inch_1/Photos/logo/020-swimsuit.png
new file mode 100644
index 00000000..beef37af
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/logo/020-swimsuit.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/logo/022-lifeguard.png b/res/themes/Example_0.96Inch_1/Photos/logo/022-lifeguard.png
new file mode 100644
index 00000000..5e8fd2e2
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/logo/022-lifeguard.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/logo/024-fishing.png b/res/themes/Example_0.96Inch_1/Photos/logo/024-fishing.png
new file mode 100644
index 00000000..01243855
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/logo/024-fishing.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/logo/031-lemonade.png b/res/themes/Example_0.96Inch_1/Photos/logo/031-lemonade.png
new file mode 100644
index 00000000..f5016b0c
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/logo/031-lemonade.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/logo/037-map.png b/res/themes/Example_0.96Inch_1/Photos/logo/037-map.png
new file mode 100644
index 00000000..d053df4b
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/logo/037-map.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/logo/048-world map.png b/res/themes/Example_0.96Inch_1/Photos/logo/048-world map.png
new file mode 100644
index 00000000..131ad3b7
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/logo/048-world map.png differ
diff --git a/res/themes/Example_0.96Inch_1/Photos/logo/049-catamaran.png b/res/themes/Example_0.96Inch_1/Photos/logo/049-catamaran.png
new file mode 100644
index 00000000..bd23c1ff
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/Photos/logo/049-catamaran.png differ
diff --git a/res/themes/Example_0.96Inch_1/background.png b/res/themes/Example_0.96Inch_1/background.png
new file mode 100644
index 00000000..cb1209bc
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/background.png differ
diff --git a/res/themes/Example_0.96Inch_1/preview.png b/res/themes/Example_0.96Inch_1/preview.png
new file mode 100644
index 00000000..6af95763
Binary files /dev/null and b/res/themes/Example_0.96Inch_1/preview.png differ
diff --git a/res/themes/Example_0.96Inch_1/theme.yaml b/res/themes/Example_0.96Inch_1/theme.yaml
new file mode 100644
index 00000000..fbba4d38
--- /dev/null
+++ b/res/themes/Example_0.96Inch_1/theme.yaml
@@ -0,0 +1,333 @@
+# Copyright (C) 2024-2024 WeAct Studio
+# Imported from https://github.com/WeActStudio/WeActStudio.SystemMonitor
+author: '@WeActStudio'
+display:
+ DISPLAY_SIZE: 0.96"
+ DISPLAY_ORIENTATION: portrait
+ DISPLAY_RGB_LED: 85, 85, 85
+
+static_images:
+ background:
+ PATH: background.png
+ X: 0
+ Y: 0
+ WIDTH: 80
+ HEIGHT: 160
+ picture:
+ PATH: Photos/logo/013-sun umbrella.png
+ X: 10
+ Y: 2
+ WIDTH: 60
+ HEIGHT: 60
+
+static_text:
+ CPU:
+ TEXT: 'CPU:'
+ X: 5
+ Y: 90
+ WIDTH: 0
+ HEIGHT: 0
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 255, 255, 255
+ BACKGROUND_IMAGE: background.png
+ ALIGN: left
+ ANCHOR: lt
+ RAM:
+ TEXT: 'RAM:'
+ X: 5
+ Y: 110
+ WIDTH: 0
+ HEIGHT: 0
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 255, 255, 255
+ BACKGROUND_IMAGE: background.png
+ ALIGN: left
+ ANCHOR: lt
+ GPU:
+ TEXT: 'GPU:'
+ X: 5
+ Y: 130
+ WIDTH: 0
+ HEIGHT: 0
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 255, 255, 255
+ BACKGROUND_IMAGE: background.png
+ ALIGN: left
+ ANCHOR: lt
+
+STATS:
+ CPU:
+ PERCENTAGE:
+ # In seconds. Longer intervals cause this to refresh more slowly.
+ # Setting to lower values will display near real time data,
+ # but may cause significant CPU usage or the display not to update properly
+ INTERVAL: 1
+ TEXT:
+ SHOW: true
+ SHOW_UNIT: true
+ UNIT_ML: false
+ MIN_SIZE: 0
+ X: 48
+ Y: 90
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ ALIGN: right # left / center / right
+ ANCHOR: rt # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
+ GRAPH:
+ SHOW: true
+ X: 5
+ Y: 100
+ WIDTH: 70
+ HEIGHT: 5
+ MIN_VALUE: 0
+ MAX_VALUE: 100
+ BAR_COLOR: 0, 255, 0
+ BAR_OUTLINE: true
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ TEMPERATURE:
+ # In seconds. Longer intervals cause this to refresh more slowly.
+ # Setting to lower values will display near real time data,
+ # but may cause significant CPU usage or the display not to update properly
+ INTERVAL: 5
+ TEXT:
+ SHOW: true
+ SHOW_UNIT: true
+ UNIT_ML: false
+ MIN_SIZE: 0
+ X: 75
+ Y: 89
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 0 # Uncomment to force a static width
+ HEIGHT: 0 # Uncomment to force static height
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 255, 255, 255
+ BACKGROUND_IMAGE: background.png
+ ALIGN: right # left / center / right
+ ANCHOR: rt # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
+ MEMORY:
+ # In seconds. Longer intervals cause this to refresh more slowly.
+ # Setting to lower values will display near real time data,
+ # but may cause significant CPU usage or the display not to update properly
+ INTERVAL: 5
+ VIRTUAL:
+ GRAPH:
+ SHOW: true
+ X: 5
+ Y: 120
+ WIDTH: 70
+ HEIGHT: 5
+ MIN_VALUE: 0
+ MAX_VALUE: 100
+ BAR_COLOR: 255, 128, 0
+ BAR_OUTLINE: true
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ PERCENT_TEXT:
+ SHOW: true
+ SHOW_UNIT: true
+ UNIT_ML: false
+ MIN_SIZE: 0
+ X: 48
+ Y: 110
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 0 # Uncomment to force a static width
+ HEIGHT: 0 # Uncomment to force static height
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ ALIGN: right # left / center / right
+ ANCHOR: rt # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
+ GPU:
+ # In seconds. Longer intervals cause this to refresh more slowly.
+ # Setting to lower values will display near real time data,
+ # but may cause significant CPU usage or the display not to update properly
+ # Note: refresh interval is common to all GPU sensors
+ INTERVAL: 1
+ PERCENTAGE:
+ GRAPH:
+ SHOW: true
+ X: 5
+ Y: 142
+ WIDTH: 70
+ HEIGHT: 5
+ MIN_VALUE: 0
+ MAX_VALUE: 100
+ BAR_COLOR: 255, 0, 0
+ BAR_OUTLINE: true
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ TEXT:
+ SHOW: true
+ SHOW_UNIT: true
+ UNIT_ML: false
+ MIN_SIZE: 0
+ X: 48
+ Y: 130
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 0 # Uncomment to force a static width
+ HEIGHT: 0 # Uncomment to force static height
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ ALIGN: right # left / center / right
+ ANCHOR: rt # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
+ TEMPERATURE:
+ TEXT:
+ SHOW: true
+ SHOW_UNIT: true
+ UNIT_ML: false
+ MIN_SIZE: 0
+ X: 75
+ Y: 129
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 0 # Uncomment to force a static width
+ HEIGHT: 0 # Uncomment to force static height
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ ALIGN: right # left / center / right
+ ANCHOR: rt # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
+ DATE:
+ # For time display, it is recommended not to change the interval: keep to 1
+ INTERVAL: 1
+ HOUR: # Format (12/24h, timezone translations) will match your computer locale
+ TEXT:
+ FORMAT: medium # short (6:48 PM) / medium (6:48:53 PM) / long (6:48:53 PM UTC) / full (6:48:53 PM Coordinated Universal Time) / custom pattern e.g. "HH:mm:ss zzz" (6:48:53 EDT)
+ SHOW: true
+ X: 76
+ Y: 154
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 0 # Uncomment to force a static width
+ HEIGHT: 0 # Uncomment to force static height
+ FONT: fusion-pixel/fusion-pixel-12px-monospaced-zh_hans.otf
+ FONT_SIZE: 12
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ ALIGN: right # left / center / right
+ ANCHOR: rm # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
+ NET:
+ INTERVAL: 1
+ WLO:
+ UPLOAD:
+ TEXT:
+ SHOW: true
+ SHOW_UNIT: true
+ UNIT_ML: false
+ MIN_SIZE: 0
+ X: 75
+ Y: 68
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 0 # Uncomment to force a static width
+ HEIGHT: 0 # Uncomment to force static height
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 128, 255, 128
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ ALIGN: right # left / center / right
+ ANCHOR: rm # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
+ DOWNLOAD:
+ TEXT:
+ SHOW: true
+ SHOW_UNIT: true
+ UNIT_ML: false
+ MIN_SIZE: 0
+ X: 75
+ Y: 80
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 0 # Uncomment to force a static width
+ HEIGHT: 0 # Uncomment to force static height
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 128, 0
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ ALIGN: right # left / center / right
+ ANCHOR: rm # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
+ ETH:
+ UPLOAD:
+ TEXT:
+ SHOW: false
+ SHOW_UNIT: true
+ UNIT_ML: false
+ MIN_SIZE: 0
+ X: 75
+ Y: 68
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 0 # Uncomment to force a static width
+ HEIGHT: 0 # Uncomment to force static height
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 128, 255, 128
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ ALIGN: right # left / center / right
+ ANCHOR: rm # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
+ DOWNLOAD:
+ TEXT:
+ SHOW: false
+ SHOW_UNIT: true
+ UNIT_ML: false
+ MIN_SIZE: 0
+ X: 75
+ Y: 80
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 0 # Uncomment to force a static width
+ HEIGHT: 0 # Uncomment to force static height
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 128, 0
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ ALIGN: right # left / center / right
+ ANCHOR: rm # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
diff --git a/res/themes/Example_0.96Inch_2/Photos/flower/002-lavender.png b/res/themes/Example_0.96Inch_2/Photos/flower/002-lavender.png
new file mode 100644
index 00000000..1f228fef
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/flower/002-lavender.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/flower/003-dahlia.png b/res/themes/Example_0.96Inch_2/Photos/flower/003-dahlia.png
new file mode 100644
index 00000000..f78e0134
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/flower/003-dahlia.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/flower/004-sunflower.png b/res/themes/Example_0.96Inch_2/Photos/flower/004-sunflower.png
new file mode 100644
index 00000000..c5872d53
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/flower/004-sunflower.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/flower/017-bluebell.png b/res/themes/Example_0.96Inch_2/Photos/flower/017-bluebell.png
new file mode 100644
index 00000000..7c959d8b
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/flower/017-bluebell.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/flower/022-lily.png b/res/themes/Example_0.96Inch_2/Photos/flower/022-lily.png
new file mode 100644
index 00000000..bd305ffd
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/flower/022-lily.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/flower/027-geranium.png b/res/themes/Example_0.96Inch_2/Photos/flower/027-geranium.png
new file mode 100644
index 00000000..36cc8d8f
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/flower/027-geranium.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/flower/029-arugula.png b/res/themes/Example_0.96Inch_2/Photos/flower/029-arugula.png
new file mode 100644
index 00000000..3c2a0613
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/flower/029-arugula.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/flower/030-cactus.png b/res/themes/Example_0.96Inch_2/Photos/flower/030-cactus.png
new file mode 100644
index 00000000..b53c6ba3
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/flower/030-cactus.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/flower/035-garlic mustard.png b/res/themes/Example_0.96Inch_2/Photos/flower/035-garlic mustard.png
new file mode 100644
index 00000000..569582b3
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/flower/035-garlic mustard.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/flower/042-pea.png b/res/themes/Example_0.96Inch_2/Photos/flower/042-pea.png
new file mode 100644
index 00000000..b2cd0f65
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/flower/042-pea.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/flower/046-amaryllis.png b/res/themes/Example_0.96Inch_2/Photos/flower/046-amaryllis.png
new file mode 100644
index 00000000..2ffacc5a
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/flower/046-amaryllis.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/flower/048-anthurium.png b/res/themes/Example_0.96Inch_2/Photos/flower/048-anthurium.png
new file mode 100644
index 00000000..0696a468
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/flower/048-anthurium.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/flower/049-freesia.png b/res/themes/Example_0.96Inch_2/Photos/flower/049-freesia.png
new file mode 100644
index 00000000..670cee6a
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/flower/049-freesia.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/logo.png b/res/themes/Example_0.96Inch_2/Photos/logo.png
new file mode 100644
index 00000000..5ad86465
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/logo.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/logo/003-pictures.png b/res/themes/Example_0.96Inch_2/Photos/logo/003-pictures.png
new file mode 100644
index 00000000..b7e76943
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/logo/003-pictures.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/logo/004-palm tree.png b/res/themes/Example_0.96Inch_2/Photos/logo/004-palm tree.png
new file mode 100644
index 00000000..9e4bdcf6
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/logo/004-palm tree.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/logo/005-sand bucket.png b/res/themes/Example_0.96Inch_2/Photos/logo/005-sand bucket.png
new file mode 100644
index 00000000..08ae694c
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/logo/005-sand bucket.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/logo/007-ice cream.png b/res/themes/Example_0.96Inch_2/Photos/logo/007-ice cream.png
new file mode 100644
index 00000000..7a076bce
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/logo/007-ice cream.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/logo/008-sun.png b/res/themes/Example_0.96Inch_2/Photos/logo/008-sun.png
new file mode 100644
index 00000000..df2274fe
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/logo/008-sun.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/logo/013-sun umbrella.png b/res/themes/Example_0.96Inch_2/Photos/logo/013-sun umbrella.png
new file mode 100644
index 00000000..54e9175b
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/logo/013-sun umbrella.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/logo/020-swimsuit.png b/res/themes/Example_0.96Inch_2/Photos/logo/020-swimsuit.png
new file mode 100644
index 00000000..beef37af
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/logo/020-swimsuit.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/logo/022-lifeguard.png b/res/themes/Example_0.96Inch_2/Photos/logo/022-lifeguard.png
new file mode 100644
index 00000000..5e8fd2e2
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/logo/022-lifeguard.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/logo/024-fishing.png b/res/themes/Example_0.96Inch_2/Photos/logo/024-fishing.png
new file mode 100644
index 00000000..01243855
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/logo/024-fishing.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/logo/031-lemonade.png b/res/themes/Example_0.96Inch_2/Photos/logo/031-lemonade.png
new file mode 100644
index 00000000..f5016b0c
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/logo/031-lemonade.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/logo/037-map.png b/res/themes/Example_0.96Inch_2/Photos/logo/037-map.png
new file mode 100644
index 00000000..d053df4b
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/logo/037-map.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/logo/048-world map.png b/res/themes/Example_0.96Inch_2/Photos/logo/048-world map.png
new file mode 100644
index 00000000..131ad3b7
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/logo/048-world map.png differ
diff --git a/res/themes/Example_0.96Inch_2/Photos/logo/049-catamaran.png b/res/themes/Example_0.96Inch_2/Photos/logo/049-catamaran.png
new file mode 100644
index 00000000..bd23c1ff
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/Photos/logo/049-catamaran.png differ
diff --git a/res/themes/Example_0.96Inch_2/background.png b/res/themes/Example_0.96Inch_2/background.png
new file mode 100644
index 00000000..17bc983f
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/background.png differ
diff --git a/res/themes/Example_0.96Inch_2/preview.png b/res/themes/Example_0.96Inch_2/preview.png
new file mode 100644
index 00000000..02427034
Binary files /dev/null and b/res/themes/Example_0.96Inch_2/preview.png differ
diff --git a/res/themes/Example_0.96Inch_2/theme.yaml b/res/themes/Example_0.96Inch_2/theme.yaml
new file mode 100644
index 00000000..ab665ab1
--- /dev/null
+++ b/res/themes/Example_0.96Inch_2/theme.yaml
@@ -0,0 +1,266 @@
+# Copyright (C) 2024-2024 WeAct Studio
+# Imported from https://github.com/WeActStudio/WeActStudio.SystemMonitor
+author: '@WeActStudio'
+display:
+ DISPLAY_SIZE: 0.96"
+ DISPLAY_ORIENTATION: landscape
+ DISPLAY_RGB_LED: 85, 85, 85
+
+static_images:
+ background:
+ PATH: background.png
+ X: 0
+ Y: 0
+ WIDTH: 160
+ HEIGHT: 80
+ picture:
+ PATH: Photos/logo/013-sun umbrella.png
+ X: 2
+ Y: 2
+ WIDTH: 76
+ HEIGHT: 76
+
+static_text:
+ CPU:
+ TEXT: 'CPU:'
+ X: 85
+ Y: 5
+ WIDTH: 0
+ HEIGHT: 0
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 255, 255, 255
+ BACKGROUND_IMAGE: background.png
+ ALIGN: left
+ ANCHOR: lt
+ RAM:
+ TEXT: 'RAM:'
+ X: 85
+ Y: 22
+ WIDTH: 0
+ HEIGHT: 0
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 255, 255, 255
+ BACKGROUND_IMAGE: background.png
+ ALIGN: left
+ ANCHOR: lt
+ GPU:
+ TEXT: 'GPU:'
+ X: 85
+ Y: 40
+ WIDTH: 0
+ HEIGHT: 0
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 255, 255, 255
+ BACKGROUND_IMAGE: background.png
+ ALIGN: left
+ ANCHOR: lt
+
+STATS:
+ CPU:
+ PERCENTAGE:
+ # In seconds. Longer intervals cause this to refresh more slowly.
+ # Setting to lower values will display near real time data,
+ # but may cause significant CPU usage or the display not to update properly
+ INTERVAL: 1
+ TEXT:
+ SHOW: true
+ SHOW_UNIT: true
+ UNIT_ML: false
+ MIN_SIZE: 0
+ X: 130
+ Y: 5
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 0 # Uncomment to force a static width
+ HEIGHT: 0 # Uncomment to force static height
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ ALIGN: right # left / center / right
+ ANCHOR: rt # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
+ GRAPH:
+ SHOW: true
+ X: 85
+ Y: 15
+ WIDTH: 70
+ HEIGHT: 5
+ MIN_VALUE: 0
+ MAX_VALUE: 100
+ BAR_COLOR: 255, 0, 0
+ BAR_OUTLINE: true
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ TEMPERATURE:
+ # In seconds. Longer intervals cause this to refresh more slowly.
+ # Setting to lower values will display near real time data,
+ # but may cause significant CPU usage or the display not to update properly
+ INTERVAL: 5
+ TEXT:
+ SHOW: true
+ SHOW_UNIT: true
+ UNIT_ML: false
+ MIN_SIZE: 0
+ X: 155
+ Y: 4
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 0 # Uncomment to force a static width
+ HEIGHT: 0 # Uncomment to force static height
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ ALIGN: right # left / center / right
+ ANCHOR: rt # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
+ MEMORY:
+ # In seconds. Longer intervals cause this to refresh more slowly.
+ # Setting to lower values will display near real time data,
+ # but may cause significant CPU usage or the display not to update properly
+ INTERVAL: 5
+ VIRTUAL:
+ GRAPH:
+ SHOW: true
+ X: 85
+ Y: 32
+ WIDTH: 70
+ HEIGHT: 5
+ MIN_VALUE: 0
+ MAX_VALUE: 100
+ BAR_COLOR: 0, 255, 0
+ BAR_OUTLINE: true
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ PERCENT_TEXT:
+ SHOW: true
+ SHOW_UNIT: true
+ UNIT_ML: false
+ MIN_SIZE: 0
+ X: 130
+ Y: 25
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 0 # Uncomment to force a static width
+ HEIGHT: 0 # Uncomment to force static height
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ ALIGN: right # left / center / right
+ ANCHOR: rm # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
+ GPU:
+ # In seconds. Longer intervals cause this to refresh more slowly.
+ # Setting to lower values will display near real time data,
+ # but may cause significant CPU usage or the display not to update properly
+ # Note: refresh interval is common to all GPU sensors
+ INTERVAL: 1
+ PERCENTAGE:
+ GRAPH:
+ SHOW: true
+ X: 85
+ Y: 50
+ WIDTH: 70
+ HEIGHT: 5
+ MIN_VALUE: 0
+ MAX_VALUE: 100
+ BAR_COLOR: 255, 128, 0
+ BAR_OUTLINE: true
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ TEXT:
+ SHOW: true
+ SHOW_UNIT: true
+ UNIT_ML: false
+ MIN_SIZE: 0
+ X: 130
+ Y: 40
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 0 # Uncomment to force a static width
+ HEIGHT: 0 # Uncomment to force static height
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ ALIGN: right # left / center / right
+ ANCHOR: rt # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
+ TEMPERATURE:
+ TEXT:
+ SHOW: true
+ SHOW_UNIT: true
+ UNIT_ML: false
+ MIN_SIZE: 0
+ X: 155
+ Y: 39
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 0 # Uncomment to force a static width
+ HEIGHT: 0 # Uncomment to force static height
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ ALIGN: right # left / center / right
+ ANCHOR: rt # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
+ DATE:
+ # For time display, it is recommended not to change the interval: keep to 1
+ INTERVAL: 1
+ HOUR: # Format (12/24h, timezone translations) will match your computer locale
+ TEXT:
+ FORMAT: medium # short (6:48 PM) / medium (6:48:53 PM) / long (6:48:53 PM UTC) / full (6:48:53 PM Coordinated Universal Time) / custom pattern e.g. "HH:mm:ss zzz" (6:48:53 EDT)
+ SHOW: true
+ X: 155
+ Y: 62
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 0 # Uncomment to force a static width
+ HEIGHT: 0 # Uncomment to force static height
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ ALIGN: right # left / center / right
+ ANCHOR: rm # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
+ DAY: # Format (Y/M/D ordering, month/day translations...) will match your computer locale
+ TEXT:
+ FORMAT: medium # short (2/20/23) / medium (Feb 20, 2023) / long (February 20, 2023) / full (Monday, February 20, 2023) / custom pattern e.g. "yyyy.MM.dd" (2024.02.20)
+ SHOW: true
+ X: 155
+ Y: 70
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 0 # Uncomment to force a static width
+ HEIGHT: 0 # Uncomment to force static height
+ FONT: fusion-pixel/fusion-pixel-10px-monospaced-zh_hans.otf
+ FONT_SIZE: 10
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ ALIGN: right # left / center / right
+ ANCHOR: rt # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
diff --git a/res/themes/Example_0.96Inch_Clock/background.png b/res/themes/Example_0.96Inch_Clock/background.png
new file mode 100644
index 00000000..17bc983f
Binary files /dev/null and b/res/themes/Example_0.96Inch_Clock/background.png differ
diff --git a/res/themes/Example_0.96Inch_Clock/preview.png b/res/themes/Example_0.96Inch_Clock/preview.png
new file mode 100644
index 00000000..2c59c01a
Binary files /dev/null and b/res/themes/Example_0.96Inch_Clock/preview.png differ
diff --git a/res/themes/Example_0.96Inch_Clock/theme.yaml b/res/themes/Example_0.96Inch_Clock/theme.yaml
new file mode 100644
index 00000000..806dd147
--- /dev/null
+++ b/res/themes/Example_0.96Inch_Clock/theme.yaml
@@ -0,0 +1,58 @@
+# Copyright (C) 2024-2024 WeAct Studio
+# Imported from https://github.com/WeActStudio/WeActStudio.SystemMonitor
+author: '@WeActStudio'
+display:
+ DISPLAY_SIZE: 0.96"
+ DISPLAY_ORIENTATION: landscape
+ DISPLAY_RGB_LED: 85, 85, 85
+
+static_images:
+ background:
+ PATH: background.png
+ X: 0
+ Y: 0
+ WIDTH: 160
+ HEIGHT: 80
+
+STATS:
+ DATE:
+ # For time display, it is recommended not to change the interval: keep to 1
+ INTERVAL: 1
+ DAY: # Format (Y/M/D ordering, month/day translations...) will match your computer locale
+ TEXT:
+ FORMAT: yyyy.MM.dd # short (2/20/23) / medium (Feb 20, 2023) / long (February 20, 2023) / full (Monday, February 20, 2023) / custom pattern e.g. "yyyy.MM.dd" (2024.02.20)
+ SHOW: true
+ X: 0
+ Y: 50
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 160 # Uncomment to force a static width
+ HEIGHT: 20 # Uncomment to force static height
+ FONT: roboto-mono/RobotoMono-Bold.ttf
+ FONT_SIZE: 20
+ FONT_COLOR: 200, 200, 200
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ ALIGN: center # left / center / right
+ ANCHOR: mt # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
+ HOUR: # Format (12/24h, timezone translations) will match your computer locale
+ TEXT:
+ FORMAT: medium # short (6:48 PM) / medium (6:48:53 PM) / long (6:48:53 PM UTC) / full (6:48:53 PM Coordinated Universal Time) / custom pattern e.g. "HH:mm:ss zzz" (6:48:53 EDT)
+ SHOW: true
+ X: 0
+ Y: 10
+ # Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
+ # To avoid this use one of these 2 methods (or both):
+ # - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
+ # - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
+ WIDTH: 160 # Uncomment to force a static width
+ HEIGHT: 38 # Uncomment to force static height
+ FONT: geforce/GeForce-Bold.ttf
+ FONT_SIZE: 38
+ FONT_COLOR: 255, 255, 255
+ BACKGROUND_COLOR: 0, 0, 0
+ BACKGROUND_IMAGE: background.png
+ ALIGN: center # left / center / right
+ ANCHOR: mt # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
diff --git a/res/themes/Gradient/theme.yaml b/res/themes/Gradient/theme.yaml
index 70d17419..ab6e24f9 100644
--- a/res/themes/Gradient/theme.yaml
+++ b/res/themes/Gradient/theme.yaml
@@ -11,8 +11,8 @@ static_images:
PATH: background.png
X: 0
Y: 0
- WIDTH: 1920
- HEIGHT: 480
+ WIDTH: 480
+ HEIGHT: 1920
static_text:
DISK:
TEXT: DISK
diff --git a/simple-program.py b/simple-program.py
index b0665940..287c92d1 100755
--- a/simple-program.py
+++ b/simple-program.py
@@ -35,6 +35,8 @@
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
@@ -93,6 +95,12 @@ def sighandler(signum, frame):
elif REVISION == "D":
logger.info("Selected Hardware Revision D (Kipye Qiye Smart Display 3.5\")")
lcd_comm = LcdCommRevD(com_port=COM_PORT, display_width=WIDTH, display_height=HEIGHT)
+ elif REVISION == "WEACT_A":
+ logger.info("Selected Hardware WeAct Studio Display FS V1 3.5\"")
+ lcd_comm = LcdCommWeActA(com_port=COM_PORT, display_width=WIDTH, display_height=HEIGHT)
+ elif REVISION == "WEACT_B":
+ logger.info("Selected Hardware WeAct Studio Display FS V1 0.96\"")
+ lcd_comm = LcdCommWeActB(com_port=COM_PORT, display_width=WIDTH, display_height=HEIGHT)
elif REVISION == "SIMU":
logger.info("Selected Simulated LCD")
lcd_comm = LcdSimulated(display_width=WIDTH, display_height=HEIGHT)