"""Weather widget: one of four display modes (see models. WeatherWidgetConfig) backed by a pluggable provider (app/weather/'s PROVIDERS registry -- Open-Meteo or NWS) and drawn by app/weather_render. py's build() dispatch. No real "next"/"back" concept (same as whiteboard) -- a single "check now" action forces a re-fetch bypassing the normal throttle.""" from __future__ import annotations from PIL import Image from sqlalchemy.orm import Session from .. import weather_render from ..models import Frame, WeatherWidgetConfig, Widget from ..routers.common import get_or_refresh_weather_widget_data from ._shared import placeholder_image ACTION_LABELS = {"check_now": "Check for updates"} def render(db: Session, frame: Frame, widget: Widget, target_w: int, target_h: int, is_normal_wake: bool = True) -> Image.Image: """is_normal_wake is unused here -- see app/widgets/photos.py's identical note; every widget type's render() shares one call signature regardless of which ones actually care.""" cfg = db.get(WeatherWidgetConfig, widget.id) data = get_or_refresh_weather_widget_data(db, frame, widget) if data is None: return placeholder_image(target_w, target_h, ["Weather widget", "not configured yet"]) return weather_render.build( cfg.mode, data, target_w, target_h, frame.palette_rgb, cfg.units, city_label=cfg.city_label or "", interval_hours=cfg.hourly_interval_hours, ) def _check_now(db: Session, frame: Frame, widget: Widget) -> None: get_or_refresh_weather_widget_data(db, frame, widget, force=True) ACTIONS = {"check_now": _check_now}