Skip to content

Commit

Permalink
Bump pychromecast to 14.0.0 (#108374)
Browse files Browse the repository at this point in the history
* Pass unregister callback to cast HomeAssisstantController

* Update tests

* Bump pychromecast to 14.0.0

* Fix lint warning, adjust tests

* Improve test coverage
  • Loading branch information
emontnemery authored Feb 15, 2024
1 parent dc09633 commit 06a21d4
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 66 deletions.
15 changes: 11 additions & 4 deletions homeassistant/components/cast/const.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
"""Consts for Cast integration."""
from __future__ import annotations

from typing import TYPE_CHECKING

from pychromecast.controllers.homeassistant import HomeAssistantController
from typing import TYPE_CHECKING, TypedDict

from homeassistant.helpers.dispatcher import SignalType

Expand Down Expand Up @@ -33,8 +31,17 @@

# Dispatcher signal fired when a Chromecast should show a Home Assistant Cast view.
SIGNAL_HASS_CAST_SHOW_VIEW: SignalType[
HomeAssistantController, str, str, str | None
HomeAssistantControllerData, str, str, str | None
] = SignalType("cast_show_view")

CONF_IGNORE_CEC = "ignore_cec"
CONF_KNOWN_HOSTS = "known_hosts"


class HomeAssistantControllerData(TypedDict):
"""Data for creating a HomeAssistantController."""

hass_url: str
hass_uuid: str
client_id: str | None
refresh_token: str
4 changes: 2 additions & 2 deletions homeassistant/components/cast/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,10 @@ def new_media_status(self, status):
if self._valid:
self._cast_device.new_media_status(status)

def load_media_failed(self, item, error_code):
def load_media_failed(self, queue_item_id, error_code):
"""Handle reception of a new MediaStatus."""
if self._valid:
self._cast_device.load_media_failed(item, error_code)
self._cast_device.load_media_failed(queue_item_id, error_code)

def new_connection_status(self, status):
"""Handle reception of a new ConnectionStatus."""
Expand Down
7 changes: 3 additions & 4 deletions homeassistant/components/cast/home_assistant_cast.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""Home Assistant Cast integration for Cast."""
from __future__ import annotations

from pychromecast.controllers.homeassistant import HomeAssistantController
import voluptuous as vol

from homeassistant import auth, config_entries, core
Expand All @@ -11,7 +10,7 @@
from homeassistant.helpers.network import NoURLAvailableError, get_url
from homeassistant.helpers.service import async_register_admin_service

from .const import DOMAIN, SIGNAL_HASS_CAST_SHOW_VIEW
from .const import DOMAIN, SIGNAL_HASS_CAST_SHOW_VIEW, HomeAssistantControllerData

SERVICE_SHOW_VIEW = "show_lovelace_view"
ATTR_VIEW_PATH = "view_path"
Expand Down Expand Up @@ -55,7 +54,7 @@ async def handle_show_view(call: core.ServiceCall) -> None:

hass_uuid = await instance_id.async_get(hass)

controller = HomeAssistantController(
controller_data = HomeAssistantControllerData(
# If you are developing Home Assistant Cast, uncomment and set to
# your dev app id.
# app_id="5FE44367",
Expand All @@ -68,7 +67,7 @@ async def handle_show_view(call: core.ServiceCall) -> None:
dispatcher.async_dispatcher_send(
hass,
SIGNAL_HASS_CAST_SHOW_VIEW,
controller,
controller_data,
call.data[ATTR_ENTITY_ID],
call.data[ATTR_VIEW_PATH],
call.data.get(ATTR_URL_PATH),
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/cast/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
"documentation": "https://www.home-assistant.io/integrations/cast",
"iot_class": "local_polling",
"loggers": ["casttube", "pychromecast"],
"requirements": ["PyChromecast==13.1.0"],
"requirements": ["PyChromecast==14.0.0"],
"zeroconf": ["_googlecast._tcp.local."]
}
26 changes: 22 additions & 4 deletions homeassistant/components/cast/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
SIGNAL_CAST_DISCOVERED,
SIGNAL_CAST_REMOVED,
SIGNAL_HASS_CAST_SHOW_VIEW,
HomeAssistantControllerData,
)
from .discovery import setup_internal_discovery
from .helpers import (
Expand Down Expand Up @@ -389,15 +390,15 @@ def new_media_status(self, media_status):
self.media_status_received = dt_util.utcnow()
self.schedule_update_ha_state()

def load_media_failed(self, item, error_code):
def load_media_failed(self, queue_item_id, error_code):
"""Handle load media failed."""
_LOGGER.debug(
"[%s %s] Load media failed with code %s(%s) for item %s",
"[%s %s] Load media failed with code %s(%s) for queue_item_id %s",
self.entity_id,
self._cast_info.friendly_name,
error_code,
MEDIA_PLAYER_ERROR_CODES.get(error_code, "unknown code"),
item,
queue_item_id,
)

def new_connection_status(self, connection_status):
Expand Down Expand Up @@ -951,7 +952,7 @@ def media_position_updated_at(self):

def _handle_signal_show_view(
self,
controller: HomeAssistantController,
controller_data: HomeAssistantControllerData,
entity_id: str,
view_path: str,
url_path: str | None,
Expand All @@ -961,6 +962,23 @@ def _handle_signal_show_view(
return

if self._hass_cast_controller is None:

def unregister() -> None:
"""Handle request to unregister the handler."""
if not self._hass_cast_controller or not self._chromecast:
return
_LOGGER.debug(
"[%s %s] Unregistering HomeAssistantController",
self.entity_id,
self._cast_info.friendly_name,
)

self._chromecast.unregister_handler(self._hass_cast_controller)
self._hass_cast_controller = None

controller = HomeAssistantController(
**controller_data, unregister=unregister
)
self._hass_cast_controller = controller
self._chromecast.register_handler(controller)

Expand Down
2 changes: 1 addition & 1 deletion requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ ProgettiHWSW==0.1.3
# PyBluez==0.22

# homeassistant.components.cast
PyChromecast==13.1.0
PyChromecast==14.0.0

# homeassistant.components.flick_electric
PyFlick==0.0.2
Expand Down
2 changes: 1 addition & 1 deletion requirements_test_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ PlexAPI==4.15.9
ProgettiHWSW==0.1.3

# homeassistant.components.cast
PyChromecast==13.1.0
PyChromecast==14.0.0

# homeassistant.components.flick_electric
PyFlick==0.0.2
Expand Down
10 changes: 10 additions & 0 deletions tests/components/cast/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ def get_chromecast_mock():
return MagicMock()


@pytest.fixture
def ha_controller_mock():
"""Mock HomeAssistantController."""
with patch(
"homeassistant.components.cast.media_player.HomeAssistantController",
MagicMock(),
) as ha_controller_mock:
yield ha_controller_mock


@pytest.fixture(autouse=True)
def cast_mock(
mz_mock,
Expand Down
14 changes: 7 additions & 7 deletions tests/components/cast/test_home_assistant_cast.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ async def test_service_show_view(hass: HomeAssistant, mock_zeroconf: None) -> No
)

assert len(calls) == 1
controller, entity_id, view_path, url_path = calls[0]
assert controller.hass_url == "https://example.com"
assert controller.client_id is None
controller_data, entity_id, view_path, url_path = calls[0]
assert controller_data["hass_url"] == "https://example.com"
assert controller_data["client_id"] is None
# Verify user did not accidentally submit their dev app id
assert controller.supporting_app_id == "A078F6B0"
assert "supporting_app_id" not in controller_data
assert entity_id == "media_player.kitchen"
assert view_path == "mock_path"
assert url_path is None
Expand Down Expand Up @@ -75,7 +75,7 @@ async def test_service_show_view_dashboard(
)

assert len(calls) == 1
_controller, entity_id, view_path, url_path = calls[0]
_controller_data, entity_id, view_path, url_path = calls[0]
assert entity_id == "media_player.kitchen"
assert view_path == "mock_path"
assert url_path == "mock-dashboard"
Expand Down Expand Up @@ -106,8 +106,8 @@ async def test_use_cloud_url(hass: HomeAssistant, mock_zeroconf: None) -> None:
)

assert len(calls) == 1
controller = calls[0][0]
assert controller.hass_url == "https://something.nabu.casa"
controller_data = calls[0][0]
assert controller_data["hass_url"] == "https://something.nabu.casa"


async def test_remove_entry(hass: HomeAssistant, mock_zeroconf: None) -> None:
Expand Down
Loading

0 comments on commit 06a21d4

Please sign in to comment.