Files
epaper-dashboard/.backup/2026-08-26-active/plugins/clock.py
T
epaper-dashboardandHermes 1f142f5245 Sync to Pi: alle Features die live deployed sind
Aus dem Backup und Live-Pull vom Pi (10.11.3.144):
- dashboard.py: Grid-Linien nur im freien Hintergrund (nicht durch Widgets)
- templates/index.html: komplett redesigned mit Sidebar + Topbar + Toast + Modal
- plugins/clock.py: responsive Layout (1x1 bis 4x4)
- plugins/system.py, weather.py, minimax.py: mit Threshold-Bars und Color-Variants
- plugins/base.py: NEU — fetch_with_retry Helper (3x retry mit backoff)
  + render_error_banner für fehlgeschlagene API-Plugins
  (grosses rotes "!" Icon mit Plugin-Name und Fehler statt Crash)

Cleanup: Helfer-Chaos (renderer.py/2/3, design_a/b/c.html, clock_classic.py,
23x clock_*.png, alte test_*.py) wurde bereits im vorherigen Commit entfernt.

Co-Authored-By: Hermes <noreply@hermes.local>
2026-08-26 22:11:36 +04:00

118 lines
5.1 KiB
Python

"""Clock-Plugin: Uhrzeit + Datum, responsive fuer alle Slot-Groessen.
Layout-Strategie pro Slot-Groesse:
is_small (1x1 ~200x120): nur Big-Time zentriert
is_wide (4x1/2x1): Time links gross, Datum rechts klein
sonst (1x2/2x2/4x4): Datum oben klein, Big-Time mittig, Wochentag unten
"""
import os, sys
from datetime import datetime
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from plugins.base import Widget
from palette import (FG, INFO, ACCENT, BLUE, OK,
measure, fit_font, centered_text,
is_small, is_wide, is_tall)
class Widget(Widget):
name = "clock"
label = "Uhrzeit / Datum"
description = "Aktuelle Uhrzeit und Datum. Responsiv fuer 1x1 bis 4x4 Slots."
category = "info"
config_schema = [
{"key": "format_24h", "label": "24-Stunden-Format", "type": "bool", "default": True},
{"key": "show_seconds", "label": "Sekunden anzeigen", "type": "bool", "default": False},
{"key": "show_date", "label": "Datum anzeigen", "type": "bool", "default": True},
{"key": "show_weekday", "label": "Wochentag anzeigen", "type": "bool", "default": True},
{"key": "accent_color", "label": "Akzentfarbe",
"type": "select",
"choices": ["info", "blue", "accent", "ok", "warn", "alert"],
"default": "info",
"help": "Farbe fuer Datum und Wochentag"},
{"key": "weekday_color", "label": "Wochentag-Farbe",
"type": "select",
"choices": ["accent", "blue", "info", "ok", "warn", "alert"],
"default": "accent"},
]
default_config = {
"format_24h": True, "show_seconds": False,
"show_date": True, "show_weekday": True,
"accent_color": "info", "weekday_color": "accent",
}
def fetch(self):
return {}
def render(self, draw, fonts, x, y, w, h):
from palette import fill_for
now = datetime.now()
pad = 10
time_str = now.strftime("%H:%M:%S" if self.cfg("show_seconds") else "%H:%M")
date_str = now.strftime("%d %b %Y")
day_str = now.strftime("%A").upper()
accent = fill_for(self.cfg("accent_color", "info"))
weekday_c = fill_for(self.cfg("weekday_color", "accent"))
# === Mini-Modus: 1x1 oder sehr klein ===
if is_small(w, h):
font = fit_font(draw, time_str, fonts, w - 2 * pad, h - 2 * pad)
centered_text(draw, time_str, x, y, w, h, font, FG)
return
# === Wide-Strip-Modus: 4x1 oder 2x1 ===
if is_wide(w, h):
# Big Time links
font_time = fit_font(draw, time_str, fonts, w // 2 - 2 * pad, h - 2 * pad)
centered_text(draw, time_str, x, y, w // 2, h, font_time, FG)
# Datum + Wochentag rechts
if self.cfg("show_date"):
font_date = fit_font(draw, date_str, fonts, w // 2 - 2 * pad, h // 2 - 4)
centered_text(draw, date_str, x + w // 2, y, w // 2, h // 2, font_date, accent)
if self.cfg("show_weekday"):
font_day = fit_font(draw, day_str, fonts, w // 2 - 2 * pad, h // 2 - 4)
centered_text(draw, day_str, x + w // 2, y + h // 2, w // 2, h // 2, font_day, weekday_c)
return
# === Tall-Modus: schmal aber hoch ===
if is_tall(w, h):
# Vertikal: Time oben, dann Date, dann Weekday
font_time = fit_font(draw, time_str, fonts, w - 2 * pad, int(h * 0.45))
centered_text(draw, time_str, x, y, w, int(h * 0.45), font_time, FG)
if self.cfg("show_date"):
font_date = fit_font(draw, date_str, fonts, w - 2 * pad, int(h * 0.25))
centered_text(draw, date_str, x, y + int(h * 0.45), w, int(h * 0.25), font_date, accent)
if self.cfg("show_weekday"):
font_day = fit_font(draw, day_str, fonts, w - 2 * pad, int(h * 0.20))
centered_text(draw, day_str, x, y + int(h * 0.70), w, int(h * 0.20), font_day, weekday_c)
return
# === Standard-Modus: 2x2 oder groesser, quadratisch oder landscape ===
# Drei Sektionen: Date (15%) | Time (60%) | Weekday (25%)
date_h = int(h * 0.18) if self.cfg("show_date") else 0
weekday_h = int(h * 0.18) if self.cfg("show_weekday") else 0
time_h = h - date_h - weekday_h
cur_y = y
if self.cfg("show_date"):
font_date = fit_font(draw, date_str, fonts, w - 2 * pad, date_h - 4)
centered_text(draw, date_str, x, cur_y, w, date_h, font_date, accent)
cur_y += date_h
time_x = x
time_w = w
# Wenn weekday und date beide aus: Time zentriert ueber alles
if not (self.cfg("show_date") or self.cfg("show_weekday")):
time_y = y
else:
time_y = cur_y
font_time = fit_font(draw, time_str, fonts, time_w - 2 * pad, time_h - 4)
centered_text(draw, time_str, time_x, time_y, time_w, time_h, font_time, FG)
cur_y += time_h
if self.cfg("show_weekday"):
font_day = fit_font(draw, day_str, fonts, w - 2 * pad, weekday_h - 4)
centered_text(draw, day_str, x, cur_y, w, weekday_h, font_day, weekday_c)