diff --git a/homeassistant/components/samsungtv/media_player.py b/homeassistant/components/samsungtv/media_player.py index 5822bafcc55..7efdcdcd439 100644 --- a/homeassistant/components/samsungtv/media_player.py +++ b/homeassistant/components/samsungtv/media_player.py @@ -21,6 +21,7 @@ from homeassistant.components.media_player.const import ( ) from homeassistant.config_entries import SOURCE_REAUTH from homeassistant.const import CONF_HOST, CONF_MAC, CONF_NAME, STATE_OFF, STATE_ON +from homeassistant.helpers import entity_component import homeassistant.helpers.config_validation as cv from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC from homeassistant.helpers.script import Script @@ -50,6 +51,13 @@ SUPPORT_SAMSUNGTV = ( | SUPPORT_PLAY_MEDIA ) +# Since the TV will take a few seconds to go to sleep +# and actually be seen as off, we need to wait just a bit +# more than the next scan interval +SCAN_INTERVAL_PLUS_OFF_TIME = entity_component.DEFAULT_SCAN_INTERVAL + timedelta( + seconds=5 +) + async def async_setup_entry(hass, entry, async_add_entities): """Set up the Samsung TV from a config entry.""" @@ -148,7 +156,12 @@ class SamsungTVDevice(MediaPlayerEntity): """Return the availability of the device.""" if self._auth_failed: return False - return self._state == STATE_ON or self._on_script or self._mac + return ( + self._state == STATE_ON + or self._on_script + or self._mac + or self._power_off_in_progress() + ) @property def device_info(self): @@ -187,7 +200,7 @@ class SamsungTVDevice(MediaPlayerEntity): def turn_off(self): """Turn off media player.""" - self._end_of_power_off = dt_util.utcnow() + timedelta(seconds=15) + self._end_of_power_off = dt_util.utcnow() + SCAN_INTERVAL_PLUS_OFF_TIME self.send_key("KEY_POWEROFF") # Force closing of remote session to provide instant UI feedback diff --git a/tests/components/samsungtv/test_media_player.py b/tests/components/samsungtv/test_media_player.py index 02eceeaacb7..2cdd5cf56df 100644 --- a/tests/components/samsungtv/test_media_player.py +++ b/tests/components/samsungtv/test_media_player.py @@ -419,6 +419,18 @@ async def test_state_without_turnon(hass, remote): assert await hass.services.async_call( DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_ID_NOTURNON}, True ) + state = hass.states.get(ENTITY_ID_NOTURNON) + # Should be STATE_UNAVAILABLE after the timer expires + assert state.state == STATE_OFF + + next_update = dt_util.utcnow() + timedelta(seconds=20) + with patch( + "homeassistant.components.samsungtv.bridge.Remote", + side_effect=OSError, + ), patch("homeassistant.util.dt.utcnow", return_value=next_update): + async_fire_time_changed(hass, next_update) + await hass.async_block_till_done() + state = hass.states.get(ENTITY_ID_NOTURNON) # Should be STATE_UNAVAILABLE since there is no way to turn it back on assert state.state == STATE_UNAVAILABLE