74 lines
2.7 KiB
Python
74 lines
2.7 KiB
Python
"""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)
|