diff --git a/homeassistant/components/media_player/cast.py b/homeassistant/components/media_player/cast.py index ae9589c7886a5b80dea1629db33eaf7d4a6a48ef..2954e427ed5430355a3cab9caf7149a57f6052af 100644 --- a/homeassistant/components/media_player/cast.py +++ b/homeassistant/components/media_player/cast.py @@ -73,7 +73,8 @@ class ChromecastInfo: port = attr.ib(type=int) uuid = attr.ib(type=Optional[str], converter=attr.converters.optional(str), default=None) # always convert UUID to string if not None - model_name = attr.ib(type=str, default='') # needed for cast type + manufacturer = attr.ib(type=str, default='') + model_name = attr.ib(type=str, default='') friendly_name = attr.ib(type=Optional[str], default=None) @property @@ -111,6 +112,7 @@ def _fill_out_missing_chromecast_info(info: ChromecastInfo) -> ChromecastInfo: host=info.host, port=info.port, uuid=(info.uuid or http_device_status.uuid), friendly_name=(info.friendly_name or http_device_status.friendly_name), + manufacturer=(info.manufacturer or http_device_status.manufacturer), model_name=(info.model_name or http_device_status.model_name) ) @@ -148,7 +150,13 @@ def _setup_internal_discovery(hass: HomeAssistantType) -> None: def internal_callback(name): """Handle zeroconf discovery of a new chromecast.""" mdns = listener.services[name] - _discover_chromecast(hass, ChromecastInfo(*mdns)) + _discover_chromecast(hass, ChromecastInfo( + host=mdns[0], + port=mdns[1], + uuid=mdns[2], + model_name=mdns[3], + friendly_name=mdns[4], + )) _LOGGER.debug("Starting internal pychromecast discovery.") listener, browser = pychromecast.start_discovery(internal_callback) @@ -365,7 +373,10 @@ class CastDevice(MediaPlayerDevice): # pylint: disable=protected-access _LOGGER.debug("Connecting to cast device %s", cast_info) chromecast = await self.hass.async_add_job( - pychromecast._get_chromecast_from_host, attr.astuple(cast_info)) + pychromecast._get_chromecast_from_host, ( + cast_info.host, cast_info.port, cast_info.uuid, + cast_info.model_name, cast_info.friendly_name + )) self._chromecast = chromecast self._status_listener = CastStatusListener(self, chromecast) # Initialise connection status as connected because we can only @@ -494,6 +505,23 @@ class CastDevice(MediaPlayerDevice): """Return the name of the device.""" return self._cast_info.friendly_name + @property + def device_info(self): + """Return information about the device.""" + cast_info = self._cast_info + + if cast_info.model_name == "Google Cast Group": + return None + + return { + 'name': cast_info.friendly_name, + 'identifiers': { + (CAST_DOMAIN, cast_info.uuid.replace('-', '')) + }, + 'model': cast_info.model_name, + 'manufacturer': cast_info.manufacturer, + } + @property def state(self): """Return the state of the player.""" diff --git a/tests/components/media_player/test_cast.py b/tests/components/media_player/test_cast.py index 8fe285a59cd74a9978436243320aee6c2129f8f9..7345fd0c1582a316dfd19f3e78751a4a803fc04d 100644 --- a/tests/components/media_player/test_cast.py +++ b/tests/components/media_player/test_cast.py @@ -77,7 +77,10 @@ async def async_setup_cast_internal_discovery(hass, config=None, def discover_chromecast(service_name: str, info: ChromecastInfo) -> None: """Discover a chromecast device.""" - listener.services[service_name] = attr.astuple(info) + listener.services[service_name] = ( + info.host, info.port, info.uuid, info.model_name, + info.friendly_name + ) discovery_callback(service_name) return discover_chromecast, add_entities @@ -152,8 +155,7 @@ async def test_internal_discovery_callback_only_generates_once(hass): discover_cast('the-service', info) await hass.async_block_till_done() discover = signal.mock_calls[0][1][0] - # attr's __eq__ somehow breaks here, use tuples instead - assert attr.astuple(discover) == attr.astuple(info) + assert discover == info signal.reset_mock() # discovering it a second time shouldn't @@ -183,8 +185,7 @@ async def test_internal_discovery_callback_fill_out(hass): # when called with incomplete info, it should use HTTP to get missing discover = signal.mock_calls[0][1][0] - # attr's __eq__ somehow breaks here, use tuples instead - assert attr.astuple(discover) == attr.astuple(full_info) + assert discover == full_info async def test_create_cast_device_without_uuid(hass):