diff --git a/homeassistant/components/samsungtv/__init__.py b/homeassistant/components/samsungtv/__init__.py index 212ef6c23ca..515e5c0de96 100644 --- a/homeassistant/components/samsungtv/__init__.py +++ b/homeassistant/components/samsungtv/__init__.py @@ -24,6 +24,7 @@ from homeassistant.core import Event, HomeAssistant, callback from homeassistant.exceptions import ConfigEntryNotReady import homeassistant.helpers.config_validation as cv from homeassistant.helpers.typing import ConfigType +from homeassistant.util.async_ import run_callback_threadsafe from .bridge import ( SamsungTVBridge, @@ -117,6 +118,19 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: # Initialize bridge bridge = await _async_create_bridge_with_updated_data(hass, entry) + # Ensure new token gets saved against the config_entry + def _update_token() -> None: + """Update config entry with the new token.""" + hass.config_entries.async_update_entry( + entry, data={**entry.data, CONF_TOKEN: bridge.token} + ) + + def new_token_callback() -> None: + """Update config entry with the new token.""" + run_callback_threadsafe(hass.loop, _update_token) + + bridge.register_new_token_callback(new_token_callback) + def stop_bridge(event: Event) -> None: """Stop SamsungTV bridge connection.""" bridge.stop() diff --git a/homeassistant/components/samsungtv/bridge.py b/homeassistant/components/samsungtv/bridge.py index ed520acc1f7..37a725ee5c9 100644 --- a/homeassistant/components/samsungtv/bridge.py +++ b/homeassistant/components/samsungtv/bridge.py @@ -98,11 +98,16 @@ class SamsungTVBridge(ABC): self.host = host self.token: str | None = None self._remote: Remote | None = None - self._callback: CALLBACK_TYPE | None = None + self._reauth_callback: CALLBACK_TYPE | None = None + self._new_token_callback: CALLBACK_TYPE | None = None def register_reauth_callback(self, func: CALLBACK_TYPE) -> None: """Register a callback function.""" - self._callback = func + self._reauth_callback = func + + def register_new_token_callback(self, func: CALLBACK_TYPE) -> None: + """Register a callback function.""" + self._new_token_callback = func @abstractmethod def try_connect(self) -> str | None: @@ -176,10 +181,15 @@ class SamsungTVBridge(ABC): except OSError: LOGGER.debug("Could not establish connection") - def _notify_callback(self) -> None: + def _notify_reauth_callback(self) -> None: """Notify access denied callback.""" - if self._callback is not None: - self._callback() + if self._reauth_callback is not None: + self._reauth_callback() + + def _notify_new_token_callback(self) -> None: + """Notify new token callback.""" + if self._new_token_callback is not None: + self._new_token_callback() class SamsungTVLegacyBridge(SamsungTVBridge): @@ -245,7 +255,7 @@ class SamsungTVLegacyBridge(SamsungTVBridge): # This is only happening when the auth was switched to DENY # A removed auth will lead to socket timeout because waiting for auth popup is just an open socket except AccessDenied: - self._notify_callback() + self._notify_reauth_callback() raise except (ConnectionClosed, OSError): pass @@ -355,7 +365,7 @@ class SamsungTVWSBridge(SamsungTVBridge): # This is only happening when the auth was switched to DENY # A removed auth will lead to socket timeout because waiting for auth popup is just an open socket except ConnectionFailure: - self._notify_callback() + self._notify_reauth_callback() except (WebSocketException, OSError): self._remote = None else: @@ -365,6 +375,7 @@ class SamsungTVWSBridge(SamsungTVBridge): self._remote.token, ) self.token = self._remote.token + self._notify_new_token_callback() return self._remote def stop(self) -> None: