diff --git a/homeassistant/components/cast/media_player.py b/homeassistant/components/cast/media_player.py
index d8eacfeede41fdb303e996136ca0cbf967d73d62..dc3d20188e7458131812152d1850c3363fec1b36 100644
--- a/homeassistant/components/cast/media_player.py
+++ b/homeassistant/components/cast/media_player.py
@@ -46,6 +46,7 @@ from homeassistant.components.media_player.const import (
 from homeassistant.components.plex.const import PLEX_URI_SCHEME
 from homeassistant.components.plex.services import lookup_plex_media
 from homeassistant.const import (
+    CAST_APP_ID_HOMEASSISTANT_LOVELACE,
     CAST_APP_ID_HOMEASSISTANT_MEDIA,
     EVENT_HOMEASSISTANT_STOP,
     STATE_IDLE,
@@ -87,6 +88,7 @@ SUPPORT_CAST = (
     | SUPPORT_TURN_ON
 )
 
+STATE_CASTING = "casting"
 
 ENTITY_SCHEMA = vol.All(
     vol.Schema(
@@ -568,14 +570,18 @@ class CastDevice(MediaPlayerEntity):
     @property
     def state(self):
         """Return the state of the player."""
-        if (media_status := self._media_status()[0]) is None:
-            return None
-        if media_status.player_is_playing:
-            return STATE_PLAYING
-        if media_status.player_is_paused:
-            return STATE_PAUSED
-        if media_status.player_is_idle:
-            return STATE_IDLE
+        # The lovelace app loops media to prevent timing out, don't show that
+        if self.app_id == CAST_APP_ID_HOMEASSISTANT_LOVELACE:
+            return STATE_CASTING
+        if (media_status := self._media_status()[0]) is not None:
+            if media_status.player_is_playing:
+                return STATE_PLAYING
+            if media_status.player_is_paused:
+                return STATE_PAUSED
+            if media_status.player_is_idle:
+                return STATE_IDLE
+        if self.app_id is not None and self.app_id != pychromecast.IDLE_APP_ID:
+            return STATE_CASTING
         if self._chromecast is not None and self._chromecast.is_idle:
             return STATE_OFF
         return None
@@ -583,12 +589,18 @@ class CastDevice(MediaPlayerEntity):
     @property
     def media_content_id(self):
         """Content ID of current playing media."""
+        # The lovelace app loops media to prevent timing out, don't show that
+        if self.app_id == CAST_APP_ID_HOMEASSISTANT_LOVELACE:
+            return None
         media_status = self._media_status()[0]
         return media_status.content_id if media_status else None
 
     @property
     def media_content_type(self):
         """Content type of current playing media."""
+        # The lovelace app loops media to prevent timing out, don't show that
+        if self.app_id == CAST_APP_ID_HOMEASSISTANT_LOVELACE:
+            return None
         if (media_status := self._media_status()[0]) is None:
             return None
         if media_status.media_is_tvshow:
@@ -602,6 +614,9 @@ class CastDevice(MediaPlayerEntity):
     @property
     def media_duration(self):
         """Duration of current playing media in seconds."""
+        # The lovelace app loops media to prevent timing out, don't show that
+        if self.app_id == CAST_APP_ID_HOMEASSISTANT_LOVELACE:
+            return None
         media_status = self._media_status()[0]
         return media_status.duration if media_status else None
 
@@ -699,6 +714,9 @@ class CastDevice(MediaPlayerEntity):
     @property
     def media_position(self):
         """Position of current playing media in seconds."""
+        # The lovelace app loops media to prevent timing out, don't show that
+        if self.app_id == CAST_APP_ID_HOMEASSISTANT_LOVELACE:
+            return None
         media_status = self._media_status()[0]
         if media_status is None or not (
             media_status.player_is_playing
@@ -714,6 +732,8 @@ class CastDevice(MediaPlayerEntity):
 
         Returns value from homeassistant.util.dt.utcnow().
         """
+        if self.app_id == CAST_APP_ID_HOMEASSISTANT_LOVELACE:
+            return None
         media_status_recevied = self._media_status()[1]
         return media_status_recevied
 
diff --git a/tests/components/cast/test_media_player.py b/tests/components/cast/test_media_player.py
index 3bb2b895c1abff156273b1b35bbc5b2e9135f88e..48ed54cb76e7078bf307579a183a2acd667afe10 100644
--- a/tests/components/cast/test_media_player.py
+++ b/tests/components/cast/test_media_player.py
@@ -45,6 +45,7 @@ FakeGroupUUID = UUID("57355bce-9364-4aa6-ac1e-eb849dccf9e3")
 def get_fake_chromecast(info: ChromecastInfo):
     """Generate a Fake Chromecast object with the specified arguments."""
     mock = MagicMock(uuid=info.uuid)
+    mock.app_id = None
     mock.media_controller.status = None
     return mock
 
@@ -565,7 +566,7 @@ async def test_entity_availability(hass: HomeAssistant):
     conn_status_cb(connection_status)
     await hass.async_block_till_done()
     state = hass.states.get(entity_id)
-    assert state.state == "unknown"
+    assert state.state == "off"
 
     connection_status = MagicMock()
     connection_status.status = "DISCONNECTED"
@@ -596,7 +597,7 @@ async def test_entity_cast_status(hass: HomeAssistant):
     state = hass.states.get(entity_id)
     assert state is not None
     assert state.name == "Speaker"
-    assert state.state == "unknown"
+    assert state.state == "off"
     assert entity_id == reg.async_get_entity_id("media_player", "cast", full_info.uuid)
 
     assert state.attributes.get("supported_features") == (
@@ -610,6 +611,17 @@ async def test_entity_cast_status(hass: HomeAssistant):
         | SUPPORT_VOLUME_SET
     )
 
+    cast_status = MagicMock()
+    cast_status.volume_level = 0.5
+    cast_status.volume_muted = False
+    cast_status_cb(cast_status)
+    await hass.async_block_till_done()
+    state = hass.states.get(entity_id)
+    # Volume hidden if no app is active
+    assert state.attributes.get("volume_level") is None
+    assert not state.attributes.get("is_volume_muted")
+
+    chromecast.app_id = "1234"
     cast_status = MagicMock()
     cast_status.volume_level = 0.5
     cast_status.volume_muted = False
@@ -665,7 +677,7 @@ async def test_entity_play_media(hass: HomeAssistant):
     state = hass.states.get(entity_id)
     assert state is not None
     assert state.name == "Speaker"
-    assert state.state == "unknown"
+    assert state.state == "off"
     assert entity_id == reg.async_get_entity_id("media_player", "cast", full_info.uuid)
 
     # Play_media
@@ -694,7 +706,7 @@ async def test_entity_play_media_cast(hass: HomeAssistant, quick_play_mock):
     state = hass.states.get(entity_id)
     assert state is not None
     assert state.name == "Speaker"
-    assert state.state == "unknown"
+    assert state.state == "off"
     assert entity_id == reg.async_get_entity_id("media_player", "cast", full_info.uuid)
 
     # Play_media - cast with app ID
@@ -739,7 +751,7 @@ async def test_entity_play_media_cast_invalid(hass, caplog, quick_play_mock):
     state = hass.states.get(entity_id)
     assert state is not None
     assert state.name == "Speaker"
-    assert state.state == "unknown"
+    assert state.state == "off"
     assert entity_id == reg.async_get_entity_id("media_player", "cast", full_info.uuid)
 
     # play_media - media_type cast with invalid JSON
@@ -812,7 +824,7 @@ async def test_entity_media_content_type(hass: HomeAssistant):
     state = hass.states.get(entity_id)
     assert state is not None
     assert state.name == "Speaker"
-    assert state.state == "unknown"
+    assert state.state == "off"
     assert entity_id == reg.async_get_entity_id("media_player", "cast", full_info.uuid)
 
     media_status = MagicMock(images=None)
@@ -866,7 +878,7 @@ async def test_entity_control(hass: HomeAssistant):
     state = hass.states.get(entity_id)
     assert state is not None
     assert state.name == "Speaker"
-    assert state.state == "unknown"
+    assert state.state == "off"
     assert entity_id == reg.async_get_entity_id("media_player", "cast", full_info.uuid)
 
     assert state.attributes.get("supported_features") == (
@@ -975,7 +987,7 @@ async def test_entity_media_states(hass: HomeAssistant):
     state = hass.states.get(entity_id)
     assert state is not None
     assert state.name == "Speaker"
-    assert state.state == "unknown"
+    assert state.state == "off"
     assert entity_id == reg.async_get_entity_id("media_player", "cast", full_info.uuid)
 
     media_status = MagicMock(images=None)
@@ -1036,7 +1048,7 @@ async def test_group_media_states(hass, mz_mock):
     state = hass.states.get(entity_id)
     assert state is not None
     assert state.name == "Speaker"
-    assert state.state == "unknown"
+    assert state.state == "off"
     assert entity_id == reg.async_get_entity_id("media_player", "cast", full_info.uuid)
 
     group_media_status = MagicMock(images=None)
@@ -1090,7 +1102,7 @@ async def test_group_media_control(hass, mz_mock):
     state = hass.states.get(entity_id)
     assert state is not None
     assert state.name == "Speaker"
-    assert state.state == "unknown"
+    assert state.state == "off"
     assert entity_id == reg.async_get_entity_id("media_player", "cast", full_info.uuid)
 
     group_media_status = MagicMock(images=None)