v.0.9.1 DigitalClock: optimzed update the display
This commit is contained in:
@@ -1,26 +1,58 @@
|
||||
from app.display.neopixel_64x64 import NeoPixel_64x64
|
||||
from app.utils import get_datetime_string
|
||||
from app.utils import get_datetime_string, text_width, find_first_mismatch
|
||||
from app.utils import colors
|
||||
|
||||
|
||||
class DigitalClock:
|
||||
CLOCK_WIDTH = 38
|
||||
stored_time_str: str = "99:99:99"
|
||||
text_color: tuple[int[3]] = colors.NEON_YELLOW
|
||||
clear_color: tuple[int[3]] = colors.BLACK
|
||||
|
||||
def __init__(self, display: NeoPixel_64x64, xpos: int, ypos: int):
|
||||
self.display = display
|
||||
self.xpos = xpos
|
||||
self.ypos = ypos
|
||||
|
||||
def _toggle_clear_color(self) -> tuple[int]:
|
||||
self.clear_color = (
|
||||
colors.BLACK if self.clear_color != colors.BLACK else colors.MAGENTA
|
||||
)
|
||||
return self.clear_color
|
||||
|
||||
def _text_width(self, text: str) -> int:
|
||||
return text_width(text, self.display.selected_font)
|
||||
|
||||
async def tick(self):
|
||||
time_str: str = get_datetime_string("time")
|
||||
time_str: str = get_datetime_string("time")[:8]
|
||||
|
||||
# ab welcher Position malen wir den String neu
|
||||
mismatch_pos: int = find_first_mismatch(self.stored_time_str, time_str)
|
||||
|
||||
untouched_part: str = time_str[:mismatch_pos]
|
||||
fresh_part: str = time_str[mismatch_pos:]
|
||||
part_to_clear: str = self.stored_time_str[mismatch_pos:]
|
||||
|
||||
print(f"untouched_part: {untouched_part}[{part_to_clear}-->{fresh_part}] ")
|
||||
|
||||
textwidth: int = self._text_width(self.stored_time_str)
|
||||
print(f"{self.stored_time_str}: #{textwidth}")
|
||||
|
||||
textwidth_untouched_part: int = self._text_width(untouched_part)
|
||||
clear_x_start_pos: int = self.xpos + textwidth_untouched_part + 1
|
||||
|
||||
textwidth_part_to_clear: int = self._text_width(part_to_clear)
|
||||
clear_x_end_pos: int = clear_x_start_pos + textwidth_part_to_clear - 1
|
||||
|
||||
self.display.clear_box(
|
||||
self.ypos,
|
||||
self.xpos,
|
||||
clear_x_start_pos,
|
||||
self.ypos + self.display.font_height,
|
||||
self.xpos + self.CLOCK_WIDTH,
|
||||
color=colors.MAGENTA,
|
||||
clear_x_end_pos,
|
||||
color=self.clear_color,
|
||||
)
|
||||
|
||||
self.display.write_text(
|
||||
time_str[:8], self.xpos, self.ypos, color=colors.NEON_YELLOW
|
||||
fresh_part, clear_x_start_pos, self.ypos, color=self.text_color
|
||||
)
|
||||
|
||||
self.stored_time_str = time_str
|
||||
|
||||
@@ -1,82 +1,108 @@
|
||||
from .math_utils import show_byte_matrix
|
||||
|
||||
|
||||
def text_width(text: str, font: dict[str, list[int]]) -> int:
|
||||
text_width_overall: int = sum([char_width(font[char]) for char in text])
|
||||
|
||||
return text_width_overall + len(text) - 1
|
||||
|
||||
|
||||
def char_width(char_matrix) -> int:
|
||||
"""Berechnung der Bits für die Zeichenbreite
|
||||
"""Berechnung der Bits für die Zeichenbreite
|
||||
|
||||
Args:
|
||||
char_matrix (int): Zeichen als Array[int]
|
||||
Args:
|
||||
char_matrix (int): Zeichen als Array[int]
|
||||
|
||||
Returns:
|
||||
int: Anzahl Bits für die Zeichenbreite
|
||||
"""
|
||||
max_val = max(char_matrix)
|
||||
Returns:
|
||||
int: Anzahl Bits für die Zeichenbreite
|
||||
"""
|
||||
max_val = max(char_matrix)
|
||||
|
||||
val = max_val
|
||||
cw = 0
|
||||
while 0xFFFFFFFF & val:
|
||||
"""rechts shiften, bis alles Nullen da sind"""
|
||||
val >>= 1
|
||||
cw += 1
|
||||
val = max_val
|
||||
cw = 0
|
||||
while 0xFFFFFFFF & val:
|
||||
"""rechts shiften, bis alles Nullen da sind"""
|
||||
val >>= 1
|
||||
cw += 1
|
||||
|
||||
return cw
|
||||
|
||||
return cw
|
||||
|
||||
def shift_letter_right(char, letter, debug=False) -> bool:
|
||||
"""Prüfe ob das Zeichen auch komplett nach rechts gezogen ist
|
||||
"""Prüfe ob das Zeichen auch komplett nach rechts gezogen ist
|
||||
|
||||
Args:
|
||||
letter (_type_): Array[0..nBytes]
|
||||
Args:
|
||||
letter (_type_): Array[0..nBytes]
|
||||
|
||||
Returns:
|
||||
bool: _description_
|
||||
"""
|
||||
Returns:
|
||||
bool: _description_
|
||||
"""
|
||||
|
||||
def isLetterRight(letter):
|
||||
def isByteRight(byte):
|
||||
return True if 1 & byte == 1 else False
|
||||
def isLetterRight(letter):
|
||||
def isByteRight(byte):
|
||||
return True if 1 & byte == 1 else False
|
||||
|
||||
for byte in letter:
|
||||
if isByteRight(byte):
|
||||
return True
|
||||
for byte in letter:
|
||||
if isByteRight(byte):
|
||||
return True
|
||||
|
||||
return False
|
||||
return False
|
||||
|
||||
def shiftLetterRight(letter):
|
||||
def shift(letter):
|
||||
return [byte >> 1 for byte in letter]
|
||||
def shiftLetterRight(letter):
|
||||
def shift(letter):
|
||||
return [byte >> 1 for byte in letter]
|
||||
|
||||
shifted = letter
|
||||
for i in range(8): # max 1 Bit's
|
||||
shifted = shift(shifted)
|
||||
if isLetterRight(shifted):
|
||||
break
|
||||
shifted = letter
|
||||
for i in range(8): # max 1 Bit's
|
||||
shifted = shift(shifted)
|
||||
if isLetterRight(shifted):
|
||||
break
|
||||
|
||||
return shifted
|
||||
return shifted
|
||||
|
||||
if isLetterRight(letter):
|
||||
return letter
|
||||
if isLetterRight(letter):
|
||||
return letter
|
||||
|
||||
# letter is not right shifted
|
||||
shifted = shiftLetterRight(letter)
|
||||
# letter is not right shifted
|
||||
shifted = shiftLetterRight(letter)
|
||||
|
||||
if debug:
|
||||
print('origin:')
|
||||
show_byte_matrix(char, letter)
|
||||
print('shifted')
|
||||
show_byte_matrix(char, shifted)
|
||||
if debug:
|
||||
print("origin:")
|
||||
show_byte_matrix(char, letter)
|
||||
print("shifted")
|
||||
show_byte_matrix(char, shifted)
|
||||
|
||||
return shifted
|
||||
|
||||
return shifted
|
||||
|
||||
def align_font(font, debug=False):
|
||||
chars = [char for char in font]
|
||||
print(chars)
|
||||
chars = [char for char in font]
|
||||
print(chars)
|
||||
|
||||
# Print the dictionary
|
||||
print('font_pretty = {')
|
||||
for char in sorted(font.keys()):
|
||||
shifted = shift_letter_right(char=char, letter=font[char], debug=debug)
|
||||
hex_values = [f'0x{val:02X}' for val in shifted]
|
||||
print(f"\t'{char}': [{', '.join(hex_values)}],")
|
||||
print('}')
|
||||
# Print the dictionary
|
||||
print("font_pretty = {")
|
||||
for char in sorted(font.keys()):
|
||||
shifted = shift_letter_right(char=char, letter=font[char], debug=debug)
|
||||
hex_values = [f"0x{val:02X}" for val in shifted]
|
||||
print(f"\t'{char}': [{', '.join(hex_values)}],")
|
||||
print("}")
|
||||
|
||||
# return f'#keys: {len(list(font.keys()))}'
|
||||
return f'#keys: {len(font)}'
|
||||
# return f'#keys: {len(list(font.keys()))}'
|
||||
return f"#keys: {len(font)}"
|
||||
|
||||
|
||||
def find_first_mismatch(str1: str, str2: str) -> int:
|
||||
"""
|
||||
Compare two strings of equal length and return the position of first mismatch.
|
||||
|
||||
Args:
|
||||
str1 (str): First string
|
||||
str2 (str): Second string (same length as str1)
|
||||
|
||||
Returns:
|
||||
int: Position of first mismatch, or -1 if strings are identical
|
||||
"""
|
||||
for i in range(len(str1)):
|
||||
if str1[i] != str2[i]:
|
||||
return i
|
||||
return -1
|
||||
|
||||
Reference in New Issue
Block a user