"""Button entities for NVIDIA Shield.""" import logging from homeassistant.components.button import ButtonEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback from .adb_session import AdbMediaSessionPoller, ensure_adb_key from .const import ( CONF_ADB_ENABLED, CONF_ADB_HOST, CONF_ADB_PORT, CONF_ANDROIDTV_ENTITY, DEFAULT_ADB_PORT, DOMAIN, ) _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: if entry.options.get(CONF_ADB_ENABLED, False): async_add_entities([NvidiaShieldPairAdbButton(hass, entry)]) class NvidiaShieldPairAdbButton(ButtonEntity): """Button to initiate or re-pair the ADB connection.""" _attr_has_entity_name = True _attr_name = "Pair ADB" _attr_icon = "mdi:link-variant" def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None: self.hass = hass self._entry = entry self._attr_unique_id = f"{DOMAIN}_{entry.entry_id}_pair_adb" @property def device_info(self) -> DeviceInfo: return DeviceInfo( identifiers={(DOMAIN, self._entry.entry_id)}, name=self._entry.title, manufacturer="NVIDIA", model="Shield TV", ) def _resolve_host(self) -> str | None: """Resolve ADB host from config or Android TV entity.""" host = self._entry.options.get(CONF_ADB_HOST) if host: return host atv_entity = self._entry.data.get(CONF_ANDROIDTV_ENTITY) if not atv_entity: return None registry = er.async_get(self.hass) entity_entry = registry.async_get(atv_entity) if not entity_entry or not entity_entry.config_entry_id: return None config_entry = self.hass.config_entries.async_get_entry(entity_entry.config_entry_id) if config_entry: return config_entry.data.get("host") return None async def async_press(self) -> None: """Attempt ADB connection. The Shield will show a pairing prompt.""" host = self._resolve_host() port = self._entry.options.get(CONF_ADB_PORT, DEFAULT_ADB_PORT) if not host: _LOGGER.error("Could not determine ADB host. Set it in integration options.") return key_path = await self.hass.async_add_executor_job( ensure_adb_key, self.hass.config.config_dir ) _LOGGER.info("Attempting ADB pairing with %s:%d — approve the prompt on the Shield", host, port) poller = AdbMediaSessionPoller(host, port, key_path) if await poller.connect(): _LOGGER.info("ADB pairing successful with %s", host) await poller.disconnect() # Reload to start polling await self.hass.config_entries.async_reload(self._entry.entry_id) else: _LOGGER.error( "ADB pairing failed with %s. Make sure Network debugging is enabled " "and you approved the prompt on the Shield.", host, ) await poller.disconnect()