From d581a66ef0694a51d60c81137e3078ef7805bf43 Mon Sep 17 00:00:00 2001 From: mcgeezy Date: Thu, 19 Mar 2026 20:33:43 -0500 Subject: [PATCH] Normalize snapshot URLs in HA integration Convert relative snapshot image_url responses to absolute URLs using configured RelayTV base_url and refresh API helper notes for /playback/play fallback semantics. --- custom_components/relaytv/__init__.py | 17 +++++++++++++++++ custom_components/relaytv/relaytv_api.py | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/custom_components/relaytv/__init__.py b/custom_components/relaytv/__init__.py index c27c51f..2cee17c 100644 --- a/custom_components/relaytv/__init__.py +++ b/custom_components/relaytv/__init__.py @@ -61,6 +61,22 @@ def _normalize_base_url(raw: str) -> str: return normalized +def _absolute_url(base_url: str, maybe_url: str | None) -> str | None: + if not maybe_url: + return None + value = str(maybe_url).strip() + if not value: + return None + parsed = urlparse(value) + if parsed.scheme in ("http", "https"): + return value + base = (base_url or "").rstrip("/") + tail = value.lstrip("/") + if not base or not tail: + return None + return f"{base}/{tail}" + + async def async_setup(hass: HomeAssistant, config: dict) -> bool: hass.data.setdefault(DOMAIN, {}) return True @@ -377,6 +393,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return data = await store[DATA_API].snapshot() or {} snapshot_url = data.get("image_url") if isinstance(data, dict) else None + snapshot_url = _absolute_url(store[DATA_API].base_url, snapshot_url) if snapshot_url: store[DATA_LAST_SNAPSHOT_URL] = snapshot_url await store[DATA_COORDINATOR].async_request_refresh() diff --git a/custom_components/relaytv/relaytv_api.py b/custom_components/relaytv/relaytv_api.py index a1338c3..221aa25 100644 --- a/custom_components/relaytv/relaytv_api.py +++ b/custom_components/relaytv/relaytv_api.py @@ -9,6 +9,7 @@ We intentionally prefer the canonical endpoints: - POST /enqueue - POST /next - POST /pause | /resume | /toggle_pause +- POST /playback/play - POST /seek_abs - POST /volume - POST /stop @@ -201,7 +202,7 @@ class RelayTVApi: async def ensure_playing(self) -> bool: """Best-effort play semantics for Home Assistant. - RelayTV does not currently expose a single "resume session or play next" endpoint. + Used as a compatibility fallback when /playback/play is unavailable. We emulate expected behavior: - If paused -> POST /resume