"""Base interface every screen implements.""" from abc import ABC, abstractmethod from typing import Any from PIL import Image class Screen(ABC): id: str display_name: str poll_interval: int = 60 # seconds between check() calls @abstractmethod def check(self, settings: dict) -> Any: """Cheap call (ideally a single small request) that returns whatever state this screen needs to render. Returning None means "nothing to show" (only meaningful for preemptive screens like Navidrome).""" @abstractmethod def render(self, state: Any, settings: dict, resolution: tuple[int, int]) -> Image.Image: """Full draw. Only called when this screen is actually about to be shown, so it's fine for this to be more expensive than check().""" def default_settings(self) -> dict: """Settings this screen needs, with defaults, merged under config.json's settings[self.id] on first run.""" return {}