"""Handles "show my digest" requests on this thin client. Division of responsibility (project-plan Phase 11.8): Home Assistant resolves *who* and *where* — which person's wake word fired in which room, whether more than one person is present, and the "whose digest?" disambiguation prompt — and sends this agent an already-resolved request. Nothing in this file looks at presence, person, or area entities, and it must stay that way: duplicating that resolution locally would create a second, un-audited answer to "whose personal section may be shown", which is exactly the question the plan says must never be guessed. This module only shows what it is told to show. """ from __future__ import annotations import json import logging from urllib.parse import urlencode from .sway_control import WS_DIGEST log = logging.getLogger(__name__) DETAIL_LEVELS = ("compact", "full") DEFAULT_DETAIL_LEVEL = "full" class DigestCanvas: def __init__(self, sway, digest_web_url: str): self.sway = sway self.digest_web_url = (digest_web_url or "").rstrip("/") self.detail_level = DEFAULT_DETAIL_LEVEL def set_detail_level(self, level: str) -> str: level = level.strip().lower() if level not in DETAIL_LEVELS: log.warning("ignoring unknown detail level %r", level) return self.detail_level self.detail_level = level log.info("detail level set to %s", level) return self.detail_level def _url(self, detail_level: str, person: str | None) -> str: params = {"detail_level": detail_level} if person: params["person"] = person return f"{self.digest_web_url}/full.html?{urlencode(params)}" def show(self, payload: str) -> None: if not self.digest_web_url: log.error("DIGEST_WEB_URL is not configured; cannot show the digest canvas") return request = {} payload = (payload or "").strip() if payload.startswith("{"): try: request = json.loads(payload) except ValueError: log.warning("could not parse digest request payload %r", payload) detail_level = str(request.get("detail_level") or self.detail_level).lower() if detail_level not in DETAIL_LEVELS: detail_level = self.detail_level # Set by the HA automation that already resolved presence. Absent means "no # personal section" — never a local fallback to a default person. person = request.get("person") or None url = self._url(detail_level, person) log.info("showing digest canvas (detail_level=%s, person=%s)", detail_level, bool(person)) self.sway.switch_workspace(WS_DIGEST) self.sway.open_url(url)