111 lines
3.9 KiB
Python
111 lines
3.9 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
import sys
|
||
|
import os
|
||
|
import numpy as np
|
||
|
import pygame
|
||
|
from datetime import datetime
|
||
|
import math
|
||
|
|
||
|
# Displaygröße
|
||
|
Nx = int(sys.argv[1]) # Breite des Displays (z.B. 80)
|
||
|
Ny = int(sys.argv[2]) # Höhe des Displays (z.B. 40)
|
||
|
|
||
|
# Initialize pygame
|
||
|
pygame.init()
|
||
|
pygame.font.init()
|
||
|
|
||
|
# Pfad zur Pixelfont im Verzeichnis "apps"
|
||
|
font_path = os.path.join('.', 'PressStart2P-Regular.ttf') # Pfad zur Schriftart
|
||
|
|
||
|
# Schriftart mit optimierter Größe laden (z.B. 16px bis 20px)
|
||
|
font_size = 16 # Geeignete Schriftgröße wählen
|
||
|
font = pygame.font.Font(font_path, font_size)
|
||
|
|
||
|
clock = pygame.time.Clock()
|
||
|
time_elapsed = 0 # Zeit-Tracker für den Farbverlauf
|
||
|
|
||
|
# Feste Farbe für den Rand (Türkis)
|
||
|
border_color = (64, 224, 208) # RGB-Werte für Türkis
|
||
|
|
||
|
# Funktion zur Berechnung der RGB-Farbe basierend auf der Zeit und der Position des Zeichens
|
||
|
def calculate_color(time_elapsed, position, total_length):
|
||
|
"""Berechnet eine RGB-Farbe basierend auf der verstrichenen Zeit und der Position des Zeichens."""
|
||
|
frequency = 2 * math.pi / total_length # Frequenz für den Regenbogenverlauf
|
||
|
phase_shift = position * frequency # Verschiebung der Phase pro Zeichen
|
||
|
|
||
|
r = int((math.sin(time_elapsed + phase_shift) + 1) * 127.5)
|
||
|
g = int((math.sin(time_elapsed + phase_shift + 2 * math.pi / 3) + 1) * 127.5)
|
||
|
b = int((math.sin(time_elapsed + phase_shift + 4 * math.pi / 3) + 1) * 127.5)
|
||
|
|
||
|
return (r, g, b)
|
||
|
|
||
|
# Funktion zum Rendern des Rahmens
|
||
|
def render_border(display_surface, Nx, Ny, border_color):
|
||
|
"""Zeichnet den Rahmen mit einer festen Farbe."""
|
||
|
# Obere Linie des Rahmens
|
||
|
for x in range(Nx):
|
||
|
display_surface.set_at((x, 0), border_color) # Oben
|
||
|
|
||
|
# Rechte Linie des Rahmens
|
||
|
for y in range(1, Ny - 1):
|
||
|
display_surface.set_at((Nx - 1, y), border_color) # Rechts
|
||
|
|
||
|
# Untere Linie des Rahmens
|
||
|
for x in range(Nx - 1, -1, -1):
|
||
|
display_surface.set_at((x, Ny - 1), border_color) # Unten
|
||
|
|
||
|
# Linke Linie des Rahmens
|
||
|
for y in range(Ny - 2, 0, -1):
|
||
|
display_surface.set_at((0, y), border_color) # Links
|
||
|
|
||
|
# Funktion zum Zeichnen der Uhrzeit
|
||
|
def render_time(display_surface, Nx, Ny, font, current_time, time_elapsed):
|
||
|
"""Zeichnet die aktuelle Uhrzeit mittig auf das Display."""
|
||
|
# Reduzierter Zeichenabstand (85% der Schriftgröße)
|
||
|
character_spacing = font_size * 0.95
|
||
|
# Breite des gesamten Textes berechnen
|
||
|
text_width = len(current_time) * character_spacing
|
||
|
|
||
|
# Horizontale und vertikale Zentrierung
|
||
|
x_offset = (Nx - text_width) // 2
|
||
|
y_offset = (Ny - font_size) // 2
|
||
|
|
||
|
# Zeichnen der Uhrzeit
|
||
|
for i, char in enumerate(current_time):
|
||
|
# Berechne die Farbe für das aktuelle Zeichen
|
||
|
text_color = calculate_color(time_elapsed, i, len(current_time))
|
||
|
# Rendern des Zeichens
|
||
|
text = font.render(char, True, text_color)
|
||
|
text_rect = text.get_rect(topleft=(x_offset + i * character_spacing, y_offset))
|
||
|
# Zeichen auf das Display zeichnen
|
||
|
display_surface.blit(text, text_rect)
|
||
|
|
||
|
# Hauptprogramm zur Anzeige der Uhrzeit
|
||
|
while True:
|
||
|
# Zeit seit Beginn des Programms
|
||
|
time_elapsed += clock.get_time() / 1000.0 # in Sekunden
|
||
|
|
||
|
# Aktuelle Zeit abrufen
|
||
|
now = datetime.now()
|
||
|
current_time = now.strftime("%H:%M") # Uhrzeit im Format HH:MM
|
||
|
|
||
|
# Ein leeres Display für die Uhrzeit erstellen
|
||
|
display_surface = pygame.Surface((Nx, Ny))
|
||
|
display_surface.fill((0, 0, 0)) # Hintergrund schwarz
|
||
|
|
||
|
# Rahmen zeichnen
|
||
|
render_border(display_surface, Nx, Ny, border_color)
|
||
|
|
||
|
# Uhrzeit zeichnen (Aufruf der neuen Funktion)
|
||
|
render_time(display_surface, Nx, Ny, font, current_time, time_elapsed)
|
||
|
|
||
|
# Sicherstellen, dass das Bild die korrekten Dimensionen hat und der Framebuffer vollständig ist
|
||
|
out = pygame.surfarray.array3d(display_surface).transpose((1, 0, 2)).astype(np.uint8).tobytes()
|
||
|
|
||
|
# Framebuffer zum Server senden
|
||
|
os.write(1, out)
|
||
|
|
||
|
clock.tick(30) # 30 FPS für flüssigen Farbverlauf
|
||
|
|