feat(client): v0.3.0 server compat — WS subprotocol auth, 429 retry, HTTPS, X-Request-ID

Aligns the integration with the four wire-level changes shipped in
media-server v0.3.0/0.3.1 without breaking back-compat with older
server versions or pre-existing config entries.

- WebSocket auth via Sec-WebSocket-Protocol: media-server.token.<T>
  (preferred by server v0.3.0+). The ?token= query is still sent so
  older servers and unauthenticated mode both keep working — aiohttp
  completes the handshake even when the server doesn't echo the
  subprotocol back.
- 429 Too Many Requests surfaced as MediaServerRateLimitError with
  Retry-After parsed; execute_script() sleeps min(retry_after, 30)
  and retries once before falling through to the caller.
- Optional HTTPS/WSS (CONF_USE_SSL) + optional certificate verification
  toggle (CONF_VERIFY_SSL) wired through the config flow, client, and
  WebSocket. Defaults preserve http+verified behaviour, so existing
  config entries are unchanged.
- X-Request-ID header (uuid4 hex) on every HTTP call so HA-side issues
  can be cross-referenced with the server's access/audit logs. The
  format matches the server's ^[A-Za-z0-9._-]{1,128}\$ allow-list so
  the id is preserved verbatim instead of being replaced server-side.

Bumps manifest version to 0.3.3.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-26 11:37:59 +03:00
parent 8e8acccbb2
commit 97c1784ad4
9 changed files with 158 additions and 16 deletions
@@ -22,9 +22,13 @@ from .const import (
DOMAIN,
CONF_TOKEN,
CONF_POLL_INTERVAL,
CONF_USE_SSL,
CONF_VERIFY_SSL,
DEFAULT_PORT,
DEFAULT_POLL_INTERVAL,
DEFAULT_NAME,
DEFAULT_USE_SSL,
DEFAULT_VERIFY_SSL,
)
_LOGGER = logging.getLogger(__name__)
@@ -52,6 +56,8 @@ async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str,
host=data[CONF_HOST],
port=data[CONF_PORT],
token=data.get(CONF_TOKEN, "") or "",
use_ssl=data.get(CONF_USE_SSL, DEFAULT_USE_SSL),
verify_ssl=data.get(CONF_VERIFY_SSL, DEFAULT_VERIFY_SSL),
)
try:
@@ -134,6 +140,12 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
type=selector.TextSelectorType.PASSWORD
)
),
vol.Optional(
CONF_USE_SSL, default=DEFAULT_USE_SSL
): selector.BooleanSelector(),
vol.Optional(
CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL
): selector.BooleanSelector(),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): selector.TextSelector(
selector.TextSelectorConfig(type=selector.TextSelectorType.TEXT)
),