refactor(config): one Shield IP field for both transports (t41)
The two address fields were the same Shield spelled twice, and every bug in the zeroconf/IP-change path came from keeping them in sync. One field now: * const.CONF_HOST replaces CONF_ADB_HOST / CONF_PROTOCOL_HOST in the setup form, the options page, the pairing forms, the reconfigure/reauth seeding and the description copy. ADB port 5555 stays the only port field; * helpers.entry_host(entry) is the single resolver (options first, then data); resolve_adb_config and the protocol settings both go through it, so both transports read the same value at call time (the t32 F1 factory re-read keeps working: the NEXT built poller sees the new address); * helpers.seed_host / seed_adb_enabled own the YAML seed's shape rule. A block may use `host` or the legacy protocol_host/adb_host keys — t41 keeps the old spelling working — and t32 F4's outcome is unchanged: a protocol-only block leaves ADB off, an address (or an explicit adb_enabled) turns it on; * the zeroconf IP-change path collapses the t21-F2 per-host dance into one rule: the discovery address IS the entry's address, so the entry is updated when it differs and left alone when it matches. The blank-self-heal and deliberately-different-ADB-host cases are gone with the duplication — a second address field cannot express them anymore, and the tests now pin that (previously "an explicit override is never clobbered"); * the options page exposes the protocol toggle it never had (the page could turn ADB off but not the protocol); * button.py (granted to this task) reads the entry's own address instead of another integration's entity. The v3 entry migration that maps existing adb_host/protocol_host onto CONF_HOST and drops the androidtv key lands in the next commit; HA runs migrations before setup, so an existing entry is never read with the old shape. Verified: 311 passed / 2 skipped, 312 / 1 with androidtvremote2, ruff clean, drift engine exit 0 on HEAD. The UI-copy contract tests (every rendered field has a label in strings.json AND translations/en.json, key trees identical, host errors name the field) drove the string edits.
This commit is contained in:
1 parent
86aa2827a2
commit
75ebeb40b0
12 files changed
+302
-276
No files matched your search
@@ -6,8 +6,10 @@ from dataclasses import dataclass
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from .const import (
|
||||
CONF_ADB_ENABLED,
|
||||
CONF_ADB_HOST,
|
||||
CONF_ADB_PORT,
|
||||
CONF_HOST,
|
||||
CONF_PROTOCOL_HOST,
|
||||
DEFAULT_ADB_PORT,
|
||||
DOMAIN,
|
||||
@@ -41,14 +43,51 @@ def protocol_cert_paths(hass: HomeAssistant) -> tuple[str, str]:
|
||||
return os.path.join(base, "client.pem"), os.path.join(base, "client.key")
|
||||
|
||||
|
||||
def entry_host(entry) -> str:
|
||||
"""The Shield's address for an entry (t41: ONE field).
|
||||
|
||||
``options`` is the source of truth; ``data`` is read as a fallback so an
|
||||
entry created by an older flow (or a hand-written seed) still resolves.
|
||||
"""
|
||||
options = getattr(entry, "options", None) or {}
|
||||
data = getattr(entry, "data", None) or {}
|
||||
return str(options.get(CONF_HOST) or data.get(CONF_HOST) or "").strip()
|
||||
|
||||
|
||||
def seed_host(block: dict) -> str:
|
||||
"""The address a YAML seed block carries (t41).
|
||||
|
||||
``host`` is the current key; the legacy ``protocol_host`` / ``adb_host``
|
||||
stay accepted so an existing configuration.yaml keeps seeding, protocol
|
||||
first (that transport is the one that cannot fall back to anything else).
|
||||
"""
|
||||
for key in (CONF_HOST, CONF_PROTOCOL_HOST, CONF_ADB_HOST):
|
||||
value = str((block or {}).get(key) or "").strip()
|
||||
if value:
|
||||
return value
|
||||
return ""
|
||||
|
||||
|
||||
def seed_adb_enabled(block: dict) -> bool:
|
||||
"""Does a seed block ask for ADB? (t32 F4's shape rule, t41's keys).
|
||||
|
||||
An explicit ``adb_enabled`` wins. Otherwise an address that names the Shield
|
||||
— the current ``host`` key or the legacy ``adb_host`` — turns ADB on, while
|
||||
a protocol-only block leaves it off.
|
||||
"""
|
||||
block = block or {}
|
||||
if CONF_ADB_ENABLED in block:
|
||||
return bool(block[CONF_ADB_ENABLED])
|
||||
return bool(block.get(CONF_HOST) or block.get(CONF_ADB_HOST))
|
||||
|
||||
|
||||
def resolve_adb_config(hass: HomeAssistant, entry) -> AdbConfig | None:
|
||||
"""Resolve host/port/key_path for the entry's ADB connection, or None.
|
||||
|
||||
Priority: the entry's own address fields (t41: no other integration is
|
||||
consulted) — the ADB field first, then the protocol field, since both
|
||||
describe the same Shield.
|
||||
Priority: the entry's own address (t41: no other integration is consulted)
|
||||
and its ADB port option.
|
||||
"""
|
||||
host = entry.options.get(CONF_ADB_HOST) or entry.options.get(CONF_PROTOCOL_HOST)
|
||||
host = entry_host(entry)
|
||||
if not host:
|
||||
return None
|
||||
port = int(entry.options.get(CONF_ADB_PORT, DEFAULT_ADB_PORT))
|
||||
|
||||
Reference in new issue
Block a user