diff --git a/homeassistant/components/samsungtv/__init__.py b/homeassistant/components/samsungtv/__init__.py index 664ce1fa439..9f605291dda 100644 --- a/homeassistant/components/samsungtv/__init__.py +++ b/homeassistant/components/samsungtv/__init__.py @@ -33,6 +33,7 @@ from .bridge import ( mac_from_device_info, ) from .const import ( + CONF_MODEL, CONF_ON_ACTION, DEFAULT_NAME, DOMAIN, @@ -149,6 +150,7 @@ async def _async_create_bridge_with_updated_data( host: str = entry.data[CONF_HOST] port: int | None = entry.data.get(CONF_PORT) method: str | None = entry.data.get(CONF_METHOD) + load_info_attempted = False info: dict[str, Any] | None = None if not port or not method: @@ -159,6 +161,7 @@ async def _async_create_bridge_with_updated_data( # When we imported from yaml we didn't setup the method # because we didn't know it port, method, info = await async_get_device_info(hass, None, host) + load_info_attempted = True if not port or not method: raise ConfigEntryNotReady( "Failed to determine connection method, make sure the device is on." @@ -171,12 +174,14 @@ async def _async_create_bridge_with_updated_data( bridge = _async_get_device_bridge(hass, {**entry.data, **updated_data}) mac: str | None = entry.data.get(CONF_MAC) + model: str | None = entry.data.get(CONF_MODEL) + if (not mac or not model) and not load_info_attempted: + info = await bridge.async_device_info() + if not mac: LOGGER.debug("Attempting to get mac for %s", host) if info: mac = mac_from_device_info(info) - else: - mac = await bridge.async_mac_from_device() if not mac: mac = await hass.async_add_executor_job( @@ -189,6 +194,22 @@ async def _async_create_bridge_with_updated_data( else: LOGGER.info("Failed to get mac for %s", host) + if not model: + LOGGER.debug("Attempting to get model for %s", host) + if info: + model = info.get("device", {}).get("modelName") + if model: + LOGGER.info("Updated model to %s for %s", model, host) + updated_data[CONF_MODEL] = model + + if model and len(model) > 4 and model[4] in ("H", "J"): + LOGGER.info( + "Detected model %s for %s. Some televisions from H and J series use " + "an encrypted protocol that may not be supported in this integration", + model, + host, + ) + if updated_data: data = {**entry.data, **updated_data} hass.config_entries.async_update_entry(entry, data=data) diff --git a/homeassistant/components/samsungtv/bridge.py b/homeassistant/components/samsungtv/bridge.py index 8fbe0572379..210bdd87cb3 100644 --- a/homeassistant/components/samsungtv/bridge.py +++ b/homeassistant/components/samsungtv/bridge.py @@ -119,10 +119,6 @@ class SamsungTVBridge(ABC): async def async_device_info(self) -> dict[str, Any] | None: """Try to gather infos of this TV.""" - @abstractmethod - async def async_mac_from_device(self) -> str | None: - """Try to fetch the mac address of the TV.""" - @abstractmethod async def async_get_app_list(self) -> dict[str, str] | None: """Get installed app list.""" @@ -169,10 +165,6 @@ class SamsungTVLegacyBridge(SamsungTVBridge): } self._remote: Remote | None = None - async def async_mac_from_device(self) -> None: - """Try to fetch the mac address of the TV.""" - return None - async def async_get_app_list(self) -> dict[str, str]: """Get installed app list.""" return {} @@ -304,11 +296,6 @@ class SamsungTVWSBridge(SamsungTVBridge): self._remote: SamsungTVWSAsyncRemote | None = None self._remote_lock = asyncio.Lock() - async def async_mac_from_device(self) -> str | None: - """Try to fetch the mac address of the TV.""" - info = await self.async_device_info() - return mac_from_device_info(info) if info else None - async def async_get_app_list(self) -> dict[str, str] | None: """Get installed app list.""" if self._app_list is None: diff --git a/tests/components/samsungtv/test_diagnostics.py b/tests/components/samsungtv/test_diagnostics.py index 47446e9103c..ba9e050d9ce 100644 --- a/tests/components/samsungtv/test_diagnostics.py +++ b/tests/components/samsungtv/test_diagnostics.py @@ -42,6 +42,7 @@ async def test_entry_diagnostics( "ip_address": "test", "mac": "aa:bb:cc:dd:ee:ff", "method": "websocket", + "model": "82GXARRS", "name": "fake", "port": 8002, "token": REDACTED, diff --git a/tests/components/samsungtv/test_init.py b/tests/components/samsungtv/test_init.py index bc815b838ed..14462b1aaf3 100644 --- a/tests/components/samsungtv/test_init.py +++ b/tests/components/samsungtv/test_init.py @@ -1,5 +1,6 @@ """Tests for the Samsung TV Integration.""" -from unittest.mock import patch +from copy import deepcopy +from unittest.mock import Mock, patch import pytest @@ -132,3 +133,18 @@ async def test_setup_duplicate_entries(hass: HomeAssistant) -> None: assert len(hass.states.async_all("media_player")) == 1 await async_setup_component(hass, SAMSUNGTV_DOMAIN, MOCK_CONFIG) assert len(hass.states.async_all("media_player")) == 1 + + +@pytest.mark.usefixtures("remotews") +async def test_setup_h_j_model( + hass: HomeAssistant, rest_api: Mock, caplog: pytest.LogCaptureFixture +) -> None: + """Test Samsung TV integration is setup.""" + device_info = deepcopy(rest_api.rest_device_info.return_value) + device_info["device"]["modelName"] = "UE48JU6400" + rest_api.rest_device_info.return_value = device_info + await async_setup_component(hass, SAMSUNGTV_DOMAIN, MOCK_CONFIG) + await hass.async_block_till_done() + state = hass.states.get(ENTITY_ID) + assert state + assert "H and J series use an encrypted protocol" in caplog.text