Skip to content

Commit

Permalink
Use pychromecast CastInfo type in cast integration (#60205)
Browse files Browse the repository at this point in the history
  • Loading branch information
emontnemery authored Nov 23, 2021
1 parent 0275778 commit 615198a
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 175 deletions.
14 changes: 2 additions & 12 deletions homeassistant/components/cast/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,7 @@ def discover_chromecast(
"""Discover a Chromecast."""

info = ChromecastInfo(
services=cast_info.services,
uuid=cast_info.uuid,
model_name=cast_info.model_name,
friendly_name=cast_info.friendly_name,
cast_type=cast_info.cast_type,
manufacturer=cast_info.manufacturer,
cast_info=cast_info,
)

if info.uuid is None:
Expand Down Expand Up @@ -76,12 +71,7 @@ def remove_cast(self, uuid, service, cast_info):
_remove_chromecast(
hass,
ChromecastInfo(
services=cast_info.services,
uuid=cast_info.uuid,
model_name=cast_info.model_name,
friendly_name=cast_info.friendly_name,
cast_type=cast_info.cast_type,
manufacturer=cast_info.manufacturer,
cast_info=cast_info,
),
)

Expand Down
31 changes: 16 additions & 15 deletions homeassistant/components/cast/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import attr
from pychromecast import dial
from pychromecast.const import CAST_TYPE_GROUP
from pychromecast.models import CastInfo


@attr.s(slots=True, frozen=True)
Expand All @@ -15,18 +16,23 @@ class ChromecastInfo:
This also has the same attributes as the mDNS fields by zeroconf.
"""

services: set | None = attr.ib()
uuid: str = attr.ib(converter=attr.converters.optional(str))
model_name: str = attr.ib()
friendly_name: str = attr.ib()
cast_type: str = attr.ib()
manufacturer: str = attr.ib()
cast_info: CastInfo = attr.ib()
is_dynamic_group = attr.ib(type=Optional[bool], default=None)

@property
def friendly_name(self) -> str:
"""Return the UUID."""
return self.cast_info.friendly_name

@property
def is_audio_group(self) -> bool:
"""Return if the cast is an audio group."""
return self.cast_type == CAST_TYPE_GROUP
return self.cast_info.cast_type == CAST_TYPE_GROUP

@property
def uuid(self) -> bool:
"""Return the UUID."""
return self.cast_info.uuid

def fill_out_missing_chromecast_info(self) -> ChromecastInfo:
"""Return a new ChromecastInfo object with missing attributes filled in.
Expand All @@ -42,21 +48,16 @@ def fill_out_missing_chromecast_info(self) -> ChromecastInfo:
http_group_status = None
http_group_status = dial.get_multizone_status(
None,
services=self.services,
services=self.cast_info.services,
zconf=ChromeCastZeroconf.get_zeroconf(),
)
if http_group_status is not None:
is_dynamic_group = any(
str(g.uuid) == self.uuid for g in http_group_status.dynamic_groups
g.uuid == self.cast_info.uuid for g in http_group_status.dynamic_groups
)

return ChromecastInfo(
services=self.services,
uuid=self.uuid,
friendly_name=self.friendly_name,
model_name=self.model_name,
cast_type=self.cast_type,
manufacturer=self.manufacturer,
cast_info=self.cast_info,
is_dynamic_group=is_dynamic_group,
)

Expand Down
40 changes: 10 additions & 30 deletions homeassistant/components/cast/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def async_cast_discovered(discover: ChromecastInfo) -> None:
"""Handle discovery of a new chromecast."""
# If wanted_uuids is set, we're only accepting specific cast devices identified
# by UUID
if wanted_uuids is not None and discover.uuid not in wanted_uuids:
if wanted_uuids is not None and str(discover.uuid) not in wanted_uuids:
# UUID not matching, ignore.
return

Expand Down Expand Up @@ -162,7 +162,6 @@ def __init__(self, cast_info: ChromecastInfo) -> None:
"""Initialize the cast device."""

self._cast_info = cast_info
self.services = cast_info.services
self._chromecast: pychromecast.Chromecast | None = None
self.cast_status = None
self.media_status = None
Expand All @@ -176,13 +175,13 @@ def __init__(self, cast_info: ChromecastInfo) -> None:

self._add_remove_handler = None
self._cast_view_remove_handler = None
self._attr_unique_id = cast_info.uuid
self._attr_unique_id = str(cast_info.uuid)
self._attr_name = cast_info.friendly_name
if cast_info.model_name != "Google Cast Group":
if cast_info.cast_info.model_name != "Google Cast Group":
self._attr_device_info = DeviceInfo(
identifiers={(CAST_DOMAIN, str(cast_info.uuid).replace("-", ""))},
manufacturer=str(cast_info.manufacturer),
model=cast_info.model_name,
manufacturer=str(cast_info.cast_info.manufacturer),
model=cast_info.cast_info.model_name,
name=str(cast_info.friendly_name),
)

Expand Down Expand Up @@ -224,20 +223,11 @@ async def async_connect_to_chromecast(self):
"[%s %s] Connecting to cast device by service %s",
self.entity_id,
self._cast_info.friendly_name,
self.services,
self._cast_info.cast_info.services,
)
chromecast = await self.hass.async_add_executor_job(
pychromecast.get_chromecast_from_cast_info,
pychromecast.discovery.CastInfo(
self.services,
self._cast_info.uuid,
self._cast_info.model_name,
self._cast_info.friendly_name,
None,
None,
self._cast_info.cast_type,
self._cast_info.manufacturer,
),
self._cast_info.cast_info,
ChromeCastZeroconf.get_zeroconf(),
)
chromecast.media_controller.app_id = CAST_APP_ID_HOMEASSISTANT_MEDIA
Expand Down Expand Up @@ -776,7 +766,6 @@ def __init__(self, hass, cast_info: ChromecastInfo):

self.hass = hass
self._cast_info = cast_info
self.services = cast_info.services
self._chromecast: pychromecast.Chromecast | None = None
self.mz_mgr = None
self._status_listener: CastStatusListener | None = None
Expand Down Expand Up @@ -824,20 +813,11 @@ async def async_connect_to_chromecast(self):
"[%s %s] Connecting to cast device by service %s",
"Dynamic group",
self._cast_info.friendly_name,
self.services,
self._cast_info.cast_info.services,
)
chromecast = await self.hass.async_add_executor_job(
pychromecast.get_chromecast_from_cast_info,
pychromecast.discovery.CastInfo(
self.services,
self._cast_info.uuid,
self._cast_info.model_name,
self._cast_info.friendly_name,
None,
None,
self._cast_info.cast_type,
self._cast_info.manufacturer,
),
self._cast_info.cast_info,
ChromeCastZeroconf.get_zeroconf(),
)
chromecast.media_controller.app_id = CAST_APP_ID_HOMEASSISTANT_MEDIA
Expand Down Expand Up @@ -889,7 +869,7 @@ async def _async_cast_removed(self, discover: ChromecastInfo):
# Removed is not our device.
return

if not discover.services:
if not discover.cast_info.services:
# Clean up the dynamic group
_LOGGER.debug("Clean up dynamic group: %s", discover)
await self.async_tear_down()
Expand Down
21 changes: 14 additions & 7 deletions tests/components/cast/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@


@pytest.fixture()
def dial_mock():
def get_multizone_status_mock():
"""Mock pychromecast dial."""
dial_mock = MagicMock()
dial_mock.get_multizone_status.return_value.dynamic_groups = []
return dial_mock
mock = MagicMock(spec_set=pychromecast.dial.get_multizone_status)
mock.return_value.dynamic_groups = []
return mock


@pytest.fixture()
Expand All @@ -23,7 +23,7 @@ def castbrowser_mock():
@pytest.fixture()
def mz_mock():
"""Mock pychromecast MultizoneManager."""
return MagicMock()
return MagicMock(spec_set=pychromecast.controllers.multizone.MultizoneManager)


@pytest.fixture()
Expand All @@ -40,15 +40,22 @@ def get_chromecast_mock():

@pytest.fixture(autouse=True)
def cast_mock(
dial_mock, mz_mock, quick_play_mock, castbrowser_mock, get_chromecast_mock
mz_mock,
quick_play_mock,
castbrowser_mock,
get_chromecast_mock,
get_multizone_status_mock,
):
"""Mock pychromecast."""
ignore_cec_orig = list(pychromecast.IGNORE_CEC)

with patch(
"homeassistant.components.cast.discovery.pychromecast.discovery.CastBrowser",
castbrowser_mock,
), patch("homeassistant.components.cast.helpers.dial", dial_mock), patch(
), patch(
"homeassistant.components.cast.helpers.dial.get_multizone_status",
get_multizone_status_mock,
), patch(
"homeassistant.components.cast.media_player.MultizoneManager",
return_value=mz_mock,
), patch(
Expand Down
Loading

0 comments on commit 615198a

Please sign in to comment.