diff --git a/homeassistant/components/vizio/media_player.py b/homeassistant/components/vizio/media_player.py index 0bff362ad317..e9cd89c635a6 100644 --- a/homeassistant/components/vizio/media_player.py +++ b/homeassistant/components/vizio/media_player.py @@ -145,6 +145,7 @@ class VizioDevice(MediaPlayerEntity): self._volume_step = config_entry.options[CONF_VOLUME_STEP] self._current_input = None self._current_app_config = None + self._app_name = None self._available_inputs = [] self._available_apps = [] self._all_apps = apps_coordinator.data if apps_coordinator else None @@ -178,9 +179,9 @@ class VizioDevice(MediaPlayerEntity): async def async_update(self) -> None: """Retrieve latest state of the device.""" - is_on = await self._device.get_power_state(log_api_exception=False) - - if is_on is None: + if ( + is_on := await self._device.get_power_state(log_api_exception=False) + ) is None: if self._attr_available: _LOGGER.warning( "Lost connection to %s", self._config_entry.data[CONF_HOST] @@ -208,18 +209,16 @@ class VizioDevice(MediaPlayerEntity): self._attr_volume_level = None self._attr_is_volume_muted = None self._current_input = None - self._attr_app_name = None + self._app_name = None self._current_app_config = None self._attr_sound_mode = None return self._attr_state = STATE_ON - audio_settings = await self._device.get_all_settings( + if audio_settings := await self._device.get_all_settings( VIZIO_AUDIO_SETTINGS, log_api_exception=False - ) - - if audio_settings: + ): self._attr_volume_level = ( float(audio_settings[VIZIO_VOLUME]) / self._max_volume ) @@ -243,14 +242,11 @@ class VizioDevice(MediaPlayerEntity): # Explicitly remove SUPPORT_SELECT_SOUND_MODE from supported features self._attr_supported_features &= ~SUPPORT_SELECT_SOUND_MODE - input_ = await self._device.get_current_input(log_api_exception=False) - if input_: + if input_ := await self._device.get_current_input(log_api_exception=False): self._current_input = input_ - inputs = await self._device.get_inputs_list(log_api_exception=False) - # If no inputs returned, end update - if not inputs: + if not (inputs := await self._device.get_inputs_list(log_api_exception=False)): return self._available_inputs = [input_.name for input_ in inputs] @@ -269,13 +265,13 @@ class VizioDevice(MediaPlayerEntity): log_api_exception=False ) - self._attr_app_name = find_app_name( + self._app_name = find_app_name( self._current_app_config, [APP_HOME, *self._all_apps, *self._additional_app_configs], ) - if self._attr_app_name == NO_APP_RUNNING: - self._attr_app_name = None + if self._app_name == NO_APP_RUNNING: + self._app_name = None def _get_additional_app_names(self) -> list[dict[str, Any]]: """Return list of additional apps that were included in configuration.yaml.""" @@ -288,7 +284,8 @@ class VizioDevice(MediaPlayerEntity): hass: HomeAssistant, config_entry: ConfigEntry ) -> None: """Send update event when Vizio config entry is updated.""" - # Move this method to component level if another entity ever gets added for a single config entry. + # Move this method to component level if another entity ever gets added for a + # single config entry. # See here: https://github.com/home-assistant/core/pull/30653#discussion_r366426121 async_dispatcher_send(hass, config_entry.entry_id, config_entry) @@ -340,8 +337,8 @@ class VizioDevice(MediaPlayerEntity): @property def source(self) -> str | None: """Return current input of the device.""" - if self._attr_app_name is not None and self._current_input in INPUT_APPS: - return self._attr_app_name + if self._app_name is not None and self._current_input in INPUT_APPS: + return self._app_name return self._current_input @@ -367,10 +364,18 @@ class VizioDevice(MediaPlayerEntity): return self._available_inputs + @property + def app_name(self) -> str | None: + """Return the name of the current app.""" + if self.source == self._app_name: + return self._app_name + + return None + @property def app_id(self) -> str | None: """Return the ID of the current app if it is unknown by pyvizio.""" - if self._current_app_config and self.app_name == UNKNOWN_APP: + if self._current_app_config and self.source == UNKNOWN_APP: return { "APP_ID": self._current_app_config.APP_ID, "NAME_SPACE": self._current_app_config.NAME_SPACE, diff --git a/tests/components/vizio/conftest.py b/tests/components/vizio/conftest.py index ffe79cb4ecf4..ad67d309cdd8 100644 --- a/tests/components/vizio/conftest.py +++ b/tests/components/vizio/conftest.py @@ -216,6 +216,22 @@ def vizio_update_with_apps_fixture(vizio_update: pytest.fixture): yield +@pytest.fixture(name="vizio_update_with_apps_on_input") +def vizio_update_with_apps_on_input_fixture(vizio_update: pytest.fixture): + """Mock valid updates to vizio device that supports apps but is on a TV input.""" + with patch( + "homeassistant.components.vizio.media_player.VizioAsync.get_inputs_list", + return_value=get_mock_inputs(INPUT_LIST_WITH_APPS), + ), patch( + "homeassistant.components.vizio.media_player.VizioAsync.get_current_input", + return_value=CURRENT_INPUT, + ), patch( + "homeassistant.components.vizio.media_player.VizioAsync.get_current_app_config", + return_value=AppConfig("unknown", 1, "app"), + ): + yield + + @pytest.fixture(name="vizio_hostname_check") def vizio_hostname_check(): """Mock vizio hostname resolution.""" diff --git a/tests/components/vizio/test_media_player.py b/tests/components/vizio/test_media_player.py index 7a030ade53fc..d3ef4019c572 100644 --- a/tests/components/vizio/test_media_player.py +++ b/tests/components/vizio/test_media_player.py @@ -751,3 +751,19 @@ async def test_apps_update( sources = hass.states.get(ENTITY_ID).attributes[ATTR_INPUT_SOURCE_LIST] apps = list(set(sources) - set(INPUT_LIST)) assert len(apps) == len(APP_LIST) + + +async def test_vizio_update_with_apps_on_input( + hass: HomeAssistant, vizio_connect, vizio_update_with_apps_on_input +) -> None: + """Test a vizio TV with apps that is on a TV input.""" + config_entry = MockConfigEntry( + domain=DOMAIN, + data=vol.Schema(VIZIO_SCHEMA)(MOCK_USER_VALID_TV_CONFIG), + unique_id=UNIQUE_ID, + ) + await _add_config_entry_to_hass(hass, config_entry) + attr = _get_attr_and_assert_base_attr(hass, DEVICE_CLASS_TV, STATE_ON) + # App name and app ID should not be in the attributes + assert "app_name" not in attr + assert "app_id" not in attr