mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Improve cleanup of Google Cast entities (#66801)
This commit is contained in:
parent
9389d1e561
commit
f1648960f5
@ -212,6 +212,10 @@ class CastDevice(MediaPlayerEntity):
|
|||||||
async def async_will_remove_from_hass(self) -> None:
|
async def async_will_remove_from_hass(self) -> None:
|
||||||
"""Disconnect Chromecast object when removed."""
|
"""Disconnect Chromecast object when removed."""
|
||||||
await self._async_disconnect()
|
await self._async_disconnect()
|
||||||
|
if self._cast_info.uuid is not None:
|
||||||
|
# Remove the entity from the added casts so that it can dynamically
|
||||||
|
# be re-added again.
|
||||||
|
self.hass.data[ADDED_CAST_DEVICES_KEY].remove(self._cast_info.uuid)
|
||||||
if self._add_remove_handler:
|
if self._add_remove_handler:
|
||||||
self._add_remove_handler()
|
self._add_remove_handler()
|
||||||
self._add_remove_handler = None
|
self._add_remove_handler = None
|
||||||
@ -253,21 +257,16 @@ class CastDevice(MediaPlayerEntity):
|
|||||||
|
|
||||||
async def _async_disconnect(self):
|
async def _async_disconnect(self):
|
||||||
"""Disconnect Chromecast object if it is set."""
|
"""Disconnect Chromecast object if it is set."""
|
||||||
if self._chromecast is None:
|
if self._chromecast is not None:
|
||||||
# Can't disconnect if not connected.
|
|
||||||
return
|
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"[%s %s] Disconnecting from chromecast socket",
|
"[%s %s] Disconnecting from chromecast socket",
|
||||||
self.entity_id,
|
self.entity_id,
|
||||||
self._cast_info.friendly_name,
|
self._cast_info.friendly_name,
|
||||||
)
|
)
|
||||||
self._attr_available = False
|
|
||||||
self.async_write_ha_state()
|
|
||||||
|
|
||||||
await self.hass.async_add_executor_job(self._chromecast.disconnect)
|
await self.hass.async_add_executor_job(self._chromecast.disconnect)
|
||||||
|
|
||||||
|
self._attr_available = False
|
||||||
self._invalidate()
|
self._invalidate()
|
||||||
|
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
def _invalidate(self):
|
def _invalidate(self):
|
||||||
@ -904,15 +903,12 @@ class DynamicCastGroup:
|
|||||||
|
|
||||||
async def _async_disconnect(self):
|
async def _async_disconnect(self):
|
||||||
"""Disconnect Chromecast object if it is set."""
|
"""Disconnect Chromecast object if it is set."""
|
||||||
if self._chromecast is None:
|
if self._chromecast is not None:
|
||||||
# Can't disconnect if not connected.
|
|
||||||
return
|
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"[%s %s] Disconnecting from chromecast socket",
|
"[%s %s] Disconnecting from chromecast socket",
|
||||||
"Dynamic group",
|
"Dynamic group",
|
||||||
self._cast_info.friendly_name,
|
self._cast_info.friendly_name,
|
||||||
)
|
)
|
||||||
|
|
||||||
await self.hass.async_add_executor_job(self._chromecast.disconnect)
|
await self.hass.async_add_executor_job(self._chromecast.disconnect)
|
||||||
|
|
||||||
self._invalidate()
|
self._invalidate()
|
||||||
|
@ -38,7 +38,7 @@ from homeassistant.const import (
|
|||||||
EVENT_HOMEASSISTANT_STOP,
|
EVENT_HOMEASSISTANT_STOP,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import entity_registry as er, network
|
from homeassistant.helpers import device_registry as dr, entity_registry as er, network
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
@ -606,6 +606,45 @@ async def test_entity_availability(hass: HomeAssistant):
|
|||||||
assert state.state == "unavailable"
|
assert state.state == "unavailable"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("port,entry_type", ((8009, None),))
|
||||||
|
async def test_device_registry(hass: HomeAssistant, port, entry_type):
|
||||||
|
"""Test device registry integration."""
|
||||||
|
entity_id = "media_player.speaker"
|
||||||
|
reg = er.async_get(hass)
|
||||||
|
dev_reg = dr.async_get(hass)
|
||||||
|
|
||||||
|
info = get_fake_chromecast_info(port=port)
|
||||||
|
|
||||||
|
chromecast, _ = await async_setup_media_player_cast(hass, info)
|
||||||
|
chromecast.cast_type = pychromecast.const.CAST_TYPE_CHROMECAST
|
||||||
|
_, conn_status_cb, _ = get_status_callbacks(chromecast)
|
||||||
|
cast_entry = hass.config_entries.async_entries("cast")[0]
|
||||||
|
|
||||||
|
connection_status = MagicMock()
|
||||||
|
connection_status.status = "CONNECTED"
|
||||||
|
conn_status_cb(connection_status)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state is not None
|
||||||
|
assert state.name == "Speaker"
|
||||||
|
assert state.state == "off"
|
||||||
|
assert entity_id == reg.async_get_entity_id("media_player", "cast", str(info.uuid))
|
||||||
|
entity_entry = reg.async_get(entity_id)
|
||||||
|
assert entity_entry.device_id is not None
|
||||||
|
device_entry = dev_reg.async_get(entity_entry.device_id)
|
||||||
|
assert device_entry.entry_type == entry_type
|
||||||
|
|
||||||
|
# Check that the chromecast object is torn down when the device is removed
|
||||||
|
chromecast.disconnect.assert_not_called()
|
||||||
|
dev_reg.async_update_device(
|
||||||
|
device_entry.id, remove_config_entry_id=cast_entry.entry_id
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
chromecast.disconnect.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
async def test_entity_cast_status(hass: HomeAssistant):
|
async def test_entity_cast_status(hass: HomeAssistant):
|
||||||
"""Test handling of cast status."""
|
"""Test handling of cast status."""
|
||||||
entity_id = "media_player.speaker"
|
entity_id = "media_player.speaker"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user