diff --git a/homeassistant/components/samsungtv/__init__.py b/homeassistant/components/samsungtv/__init__.py index 538bd2475dd..42ecb45d8b0 100644 --- a/homeassistant/components/samsungtv/__init__.py +++ b/homeassistant/components/samsungtv/__init__.py @@ -10,7 +10,7 @@ from urllib.parse import urlparse import getmac from homeassistant.components import ssdp -from homeassistant.config_entries import ConfigEntry +from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntry from homeassistant.const import ( CONF_HOST, CONF_MAC, @@ -135,6 +135,23 @@ async def async_setup_entry(hass: HomeAssistant, entry: SamsungTVConfigEntry) -> ) bridge = await _async_create_bridge_with_updated_data(hass, entry) + @callback + def _access_denied() -> None: + """Access denied callback.""" + LOGGER.debug("Access denied in getting remote object") + hass.create_task( + hass.config_entries.flow.async_init( + DOMAIN, + context={ + "source": SOURCE_REAUTH, + "entry_id": entry.entry_id, + }, + data=entry.data, + ) + ) + + bridge.register_reauth_callback(_access_denied) + # Ensure updates get saved against the config_entry @callback def _update_config_entry(updates: Mapping[str, Any]) -> None: diff --git a/homeassistant/components/samsungtv/bridge.py b/homeassistant/components/samsungtv/bridge.py index 56ed2a35b49..0b8a5d4a268 100644 --- a/homeassistant/components/samsungtv/bridge.py +++ b/homeassistant/components/samsungtv/bridge.py @@ -165,6 +165,7 @@ class SamsungTVBridge(ABC): self.host = host self.token: str | None = None self.session_id: str | None = None + self.auth_failed: bool = False self._reauth_callback: CALLBACK_TYPE | None = None self._update_config_entry: Callable[[Mapping[str, Any]], None] | None = None self._app_list_callback: Callable[[dict[str, str]], None] | None = None @@ -335,6 +336,7 @@ class SamsungTVLegacyBridge(SamsungTVBridge): # A removed auth will lead to socket timeout because waiting # for auth popup is just an open socket except AccessDenied: + self.auth_failed = True self._notify_reauth_callback() raise except (ConnectionClosed, OSError): @@ -607,6 +609,7 @@ class SamsungTVWSBridge( self.host, repr(err), ) + self.auth_failed = True self._notify_reauth_callback() self._remote = None except ConnectionClosedError as err: diff --git a/homeassistant/components/samsungtv/media_player.py b/homeassistant/components/samsungtv/media_player.py index 01e8c454bfe..12952f72d2e 100644 --- a/homeassistant/components/samsungtv/media_player.py +++ b/homeassistant/components/samsungtv/media_player.py @@ -28,7 +28,7 @@ from homeassistant.components.media_player import ( MediaPlayerState, MediaType, ) -from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntry +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv from homeassistant.helpers.aiohttp_client import async_get_clientsession @@ -37,7 +37,7 @@ from homeassistant.util.async_ import create_eager_task from . import SamsungTVConfigEntry from .bridge import SamsungTVBridge, SamsungTVWSBridge -from .const import CONF_SSDP_RENDERING_CONTROL_LOCATION, DOMAIN, LOGGER +from .const import CONF_SSDP_RENDERING_CONTROL_LOCATION, LOGGER from .entity import SamsungTVEntity SOURCES = {"TV": "KEY_TV", "HDMI": "KEY_HDMI"} @@ -105,8 +105,6 @@ class SamsungTVDevice(SamsungTVEntity, MediaPlayerEntity): if self._ssdp_rendering_control_location: self._attr_supported_features |= MediaPlayerEntityFeature.VOLUME_SET - self._auth_failed = False - self._bridge.register_reauth_callback(self.access_denied) self._bridge.register_app_list_callback(self._app_list_callback) self._dmr_device: DmrDevice | None = None @@ -132,28 +130,13 @@ class SamsungTVDevice(SamsungTVEntity, MediaPlayerEntity): self._update_sources() self._app_list_event.set() - def access_denied(self) -> None: - """Access denied callback.""" - LOGGER.debug("Access denied in getting remote object") - self._auth_failed = True - self.hass.create_task( - self.hass.config_entries.flow.async_init( - DOMAIN, - context={ - "source": SOURCE_REAUTH, - "entry_id": self._config_entry.entry_id, - }, - data=self._config_entry.data, - ) - ) - async def async_will_remove_from_hass(self) -> None: """Handle removal.""" await self._async_shutdown_dmr() async def async_update(self) -> None: """Update state of device.""" - if self._auth_failed or self.hass.is_stopping: + if self._bridge.auth_failed or self.hass.is_stopping: return old_state = self._attr_state if self._bridge.power_off_in_progress: @@ -316,7 +299,7 @@ class SamsungTVDevice(SamsungTVEntity, MediaPlayerEntity): @property def available(self) -> bool: """Return the availability of the device.""" - if self._auth_failed: + if self._bridge.auth_failed: return False return ( self.state == MediaPlayerState.ON