Optimize directv client initialization (#32706)
* Optimize directv client initialization. * Update config_flow.py * Update media_player.py * Update media_player.py * Update __init__.py * Update __init__.py * Update __init__.py * Update __init__.py * Update test_media_player.py * Update __init__.py * Update media_player.py * Update test_media_player.py * Update media_player.py * Update test_media_player.py * Update config_flow.py * Update test_config_flow.py * Update test_config_flow.py * Update test_config_flow.py * Update test_config_flow.py * Update test_config_flow.py * Update test_config_flow.py * Update __init__.py * Update test_config_flow.py * Update test_config_flow.py * Update test_media_player.py * Update test_media_player.py * Update __init__.py * Update __init__.py * Update __init__.pypull/32789/head
parent
750ed2facd
commit
5dd031af17
|
@ -32,7 +32,7 @@ def get_dtv_data(
|
|||
hass: HomeAssistant, host: str, port: int = DEFAULT_PORT, client_addr: str = "0"
|
||||
) -> dict:
|
||||
"""Retrieve a DIRECTV instance, locations list, and version info for the receiver device."""
|
||||
dtv = DIRECTV(host, port, client_addr)
|
||||
dtv = DIRECTV(host, port, client_addr, determine_state=False)
|
||||
locations = dtv.get_locations()
|
||||
version_info = dtv.get_version()
|
||||
|
||||
|
|
|
@ -29,8 +29,7 @@ def validate_input(data: Dict) -> Dict:
|
|||
|
||||
Data has the keys from DATA_SCHEMA with values provided by the user.
|
||||
"""
|
||||
# directpy does IO in constructor.
|
||||
dtv = DIRECTV(data["host"], DEFAULT_PORT)
|
||||
dtv = DIRECTV(data["host"], DEFAULT_PORT, determine_state=False)
|
||||
version_info = dtv.get_version()
|
||||
|
||||
return {
|
||||
|
@ -76,8 +75,7 @@ class DirecTVConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||
return self._show_form(errors)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception("Unexpected exception")
|
||||
errors["base"] = ERROR_UNKNOWN
|
||||
return self._show_form(errors)
|
||||
return self.async_abort(reason=ERROR_UNKNOWN)
|
||||
|
||||
await self.async_set_unique_id(info["receiver_id"])
|
||||
self._abort_if_unique_id_configured()
|
||||
|
|
|
@ -83,22 +83,6 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|||
)
|
||||
|
||||
|
||||
def get_dtv_instance(
|
||||
host: str, port: int = DEFAULT_PORT, client_addr: str = "0"
|
||||
) -> DIRECTV:
|
||||
"""Retrieve a DIRECTV instance for the receiver or client device."""
|
||||
try:
|
||||
return DIRECTV(host, port, client_addr)
|
||||
except RequestException as exception:
|
||||
_LOGGER.debug(
|
||||
"Request exception %s trying to retrieve DIRECTV instance for client address %s on device %s",
|
||||
exception,
|
||||
client_addr,
|
||||
host,
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistantType,
|
||||
entry: ConfigEntry,
|
||||
|
@ -114,16 +98,15 @@ async def async_setup_entry(
|
|||
continue
|
||||
|
||||
if loc["clientAddr"] != "0":
|
||||
# directpy does IO in constructor.
|
||||
dtv = await hass.async_add_executor_job(
|
||||
get_dtv_instance, entry.data[CONF_HOST], DEFAULT_PORT, loc["clientAddr"]
|
||||
dtv = DIRECTV(
|
||||
entry.data[CONF_HOST],
|
||||
DEFAULT_PORT,
|
||||
loc["clientAddr"],
|
||||
determine_state=False,
|
||||
)
|
||||
else:
|
||||
dtv = hass.data[DOMAIN][entry.entry_id][DATA_CLIENT]
|
||||
|
||||
if not dtv:
|
||||
continue
|
||||
|
||||
entities.append(
|
||||
DirecTvDevice(
|
||||
str.title(loc["locationName"]), loc["clientAddr"], dtv, version_info,
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
"""Tests for the DirecTV component."""
|
||||
from DirectPy import DIRECTV
|
||||
|
||||
from homeassistant.components.directv.const import DOMAIN
|
||||
from homeassistant.const import CONF_HOST
|
||||
from homeassistant.helpers.typing import HomeAssistantType
|
||||
|
@ -94,18 +96,23 @@ MOCK_GET_VERSION = {
|
|||
}
|
||||
|
||||
|
||||
class MockDirectvClass:
|
||||
class MockDirectvClass(DIRECTV):
|
||||
"""A fake DirecTV DVR device."""
|
||||
|
||||
def __init__(self, ip, port=8080, clientAddr="0"):
|
||||
def __init__(self, ip, port=8080, clientAddr="0", determine_state=False):
|
||||
"""Initialize the fake DirecTV device."""
|
||||
self._host = ip
|
||||
self._port = port
|
||||
self._device = clientAddr
|
||||
self._standby = True
|
||||
self._play = False
|
||||
super().__init__(
|
||||
ip=ip, port=port, clientAddr=clientAddr, determine_state=determine_state,
|
||||
)
|
||||
|
||||
self.attributes = LIVE
|
||||
self._play = False
|
||||
self._standby = True
|
||||
|
||||
if self.clientAddr == CLIENT_ADDRESS:
|
||||
self.attributes = RECORDING
|
||||
self._standby = False
|
||||
else:
|
||||
self.attributes = LIVE
|
||||
|
||||
def get_locations(self):
|
||||
"""Mock for get_locations method."""
|
||||
|
|
|
@ -114,9 +114,7 @@ async def test_form_cannot_connect(hass: HomeAssistantType) -> None:
|
|||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.directv.config_flow.DIRECTV", new=MockDirectvClass,
|
||||
), patch(
|
||||
"homeassistant.components.directv.config_flow.DIRECTV.get_version",
|
||||
"tests.components.directv.test_config_flow.MockDirectvClass.get_version",
|
||||
side_effect=RequestException,
|
||||
) as mock_validate_input:
|
||||
result = await async_configure_flow(hass, result["flow_id"], {CONF_HOST: HOST},)
|
||||
|
@ -135,15 +133,13 @@ async def test_form_unknown_error(hass: HomeAssistantType) -> None:
|
|||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.directv.config_flow.DIRECTV", new=MockDirectvClass,
|
||||
), patch(
|
||||
"homeassistant.components.directv.config_flow.DIRECTV.get_version",
|
||||
"tests.components.directv.test_config_flow.MockDirectvClass.get_version",
|
||||
side_effect=Exception,
|
||||
) as mock_validate_input:
|
||||
result = await async_configure_flow(hass, result["flow_id"], {CONF_HOST: HOST},)
|
||||
|
||||
assert result["type"] == RESULT_TYPE_FORM
|
||||
assert result["errors"] == {"base": "unknown"}
|
||||
assert result["type"] == RESULT_TYPE_ABORT
|
||||
assert result["reason"] == "unknown"
|
||||
|
||||
await hass.async_block_till_done()
|
||||
assert len(mock_validate_input.mock_calls) == 1
|
||||
|
@ -205,9 +201,7 @@ async def test_ssdp_discovery_confirm_abort(hass: HomeAssistantType) -> None:
|
|||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.directv.config_flow.DIRECTV", new=MockDirectvClass,
|
||||
), patch(
|
||||
"homeassistant.components.directv.config_flow.DIRECTV.get_version",
|
||||
"tests.components.directv.test_config_flow.MockDirectvClass.get_version",
|
||||
side_effect=RequestException,
|
||||
) as mock_validate_input:
|
||||
result = await async_configure_flow(hass, result["flow_id"], {})
|
||||
|
@ -227,9 +221,7 @@ async def test_ssdp_discovery_confirm_unknown_error(hass: HomeAssistantType) ->
|
|||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.directv.config_flow.DIRECTV", new=MockDirectvClass,
|
||||
), patch(
|
||||
"homeassistant.components.directv.config_flow.DIRECTV.get_version",
|
||||
"tests.components.directv.test_config_flow.MockDirectvClass.get_version",
|
||||
side_effect=Exception,
|
||||
) as mock_validate_input:
|
||||
result = await async_configure_flow(hass, result["flow_id"], {})
|
||||
|
|
|
@ -54,9 +54,7 @@ from homeassistant.util import dt as dt_util
|
|||
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
from tests.components.directv import (
|
||||
CLIENT_ADDRESS,
|
||||
DOMAIN,
|
||||
HOST,
|
||||
MOCK_GET_LOCATIONS_MULTIPLE,
|
||||
RECORDING,
|
||||
MockDirectvClass,
|
||||
|
@ -70,15 +68,6 @@ MAIN_ENTITY_ID = f"{MP_DOMAIN}.main_dvr"
|
|||
# pylint: disable=redefined-outer-name
|
||||
|
||||
|
||||
@fixture
|
||||
def client_dtv() -> MockDirectvClass:
|
||||
"""Fixture for a client device."""
|
||||
mocked_dtv = MockDirectvClass(HOST, clientAddr=CLIENT_ADDRESS)
|
||||
mocked_dtv.attributes = RECORDING
|
||||
mocked_dtv._standby = False # pylint: disable=protected-access
|
||||
return mocked_dtv
|
||||
|
||||
|
||||
@fixture
|
||||
def mock_now() -> datetime:
|
||||
"""Fixture for dtutil.now."""
|
||||
|
@ -93,34 +82,19 @@ async def setup_directv(hass: HomeAssistantType) -> MockConfigEntry:
|
|||
return await setup_integration(hass)
|
||||
|
||||
|
||||
async def setup_directv_with_instance_error(hass: HomeAssistantType) -> MockConfigEntry:
|
||||
async def setup_directv_with_locations(hass: HomeAssistantType) -> MockConfigEntry:
|
||||
"""Set up mock DirecTV integration."""
|
||||
with patch(
|
||||
"homeassistant.components.directv.DIRECTV", new=MockDirectvClass,
|
||||
), patch(
|
||||
"homeassistant.components.directv.DIRECTV.get_locations",
|
||||
"tests.components.directv.test_media_player.MockDirectvClass.get_locations",
|
||||
return_value=MOCK_GET_LOCATIONS_MULTIPLE,
|
||||
), patch(
|
||||
"homeassistant.components.directv.media_player.get_dtv_instance",
|
||||
return_value=None,
|
||||
):
|
||||
return await setup_integration(hass)
|
||||
|
||||
|
||||
async def setup_directv_with_locations(
|
||||
hass: HomeAssistantType, client_dtv: MockDirectvClass,
|
||||
) -> MockConfigEntry:
|
||||
"""Set up mock DirecTV integration."""
|
||||
with patch(
|
||||
"homeassistant.components.directv.DIRECTV", new=MockDirectvClass,
|
||||
), patch(
|
||||
"homeassistant.components.directv.DIRECTV.get_locations",
|
||||
return_value=MOCK_GET_LOCATIONS_MULTIPLE,
|
||||
), patch(
|
||||
"homeassistant.components.directv.media_player.get_dtv_instance",
|
||||
return_value=client_dtv,
|
||||
):
|
||||
return await setup_integration(hass)
|
||||
with patch(
|
||||
"homeassistant.components.directv.DIRECTV", new=MockDirectvClass,
|
||||
), patch(
|
||||
"homeassistant.components.directv.media_player.DIRECTV",
|
||||
new=MockDirectvClass,
|
||||
):
|
||||
return await setup_integration(hass)
|
||||
|
||||
|
||||
async def async_turn_on(
|
||||
|
@ -204,27 +178,17 @@ async def test_setup(hass: HomeAssistantType) -> None:
|
|||
assert hass.states.get(MAIN_ENTITY_ID)
|
||||
|
||||
|
||||
async def test_setup_with_multiple_locations(
|
||||
hass: HomeAssistantType, client_dtv: MockDirectvClass
|
||||
) -> None:
|
||||
async def test_setup_with_multiple_locations(hass: HomeAssistantType) -> None:
|
||||
"""Test setup with basic config with client location."""
|
||||
await setup_directv_with_locations(hass, client_dtv)
|
||||
await setup_directv_with_locations(hass)
|
||||
|
||||
assert hass.states.get(MAIN_ENTITY_ID)
|
||||
assert hass.states.get(CLIENT_ENTITY_ID)
|
||||
|
||||
|
||||
async def test_setup_with_instance_error(hass: HomeAssistantType) -> None:
|
||||
"""Test setup with basic config with client location that results in instance error."""
|
||||
await setup_directv_with_instance_error(hass)
|
||||
|
||||
assert hass.states.get(MAIN_ENTITY_ID)
|
||||
assert hass.states.async_entity_ids(MP_DOMAIN) == [MAIN_ENTITY_ID]
|
||||
|
||||
|
||||
async def test_unique_id(hass: HomeAssistantType, client_dtv: MockDirectvClass) -> None:
|
||||
async def test_unique_id(hass: HomeAssistantType) -> None:
|
||||
"""Test unique id."""
|
||||
await setup_directv_with_locations(hass, client_dtv)
|
||||
await setup_directv_with_locations(hass)
|
||||
|
||||
entity_registry = await hass.helpers.entity_registry.async_get_registry()
|
||||
|
||||
|
@ -235,11 +199,9 @@ async def test_unique_id(hass: HomeAssistantType, client_dtv: MockDirectvClass)
|
|||
assert client.unique_id == "2CA17D1CD30X"
|
||||
|
||||
|
||||
async def test_supported_features(
|
||||
hass: HomeAssistantType, client_dtv: MockDirectvClass
|
||||
) -> None:
|
||||
async def test_supported_features(hass: HomeAssistantType) -> None:
|
||||
"""Test supported features."""
|
||||
await setup_directv_with_locations(hass, client_dtv)
|
||||
await setup_directv_with_locations(hass)
|
||||
|
||||
# Features supported for main DVR
|
||||
state = hass.states.get(MAIN_ENTITY_ID)
|
||||
|
@ -269,10 +231,10 @@ async def test_supported_features(
|
|||
|
||||
|
||||
async def test_check_attributes(
|
||||
hass: HomeAssistantType, mock_now: dt_util.dt.datetime, client_dtv: MockDirectvClass
|
||||
hass: HomeAssistantType, mock_now: dt_util.dt.datetime
|
||||
) -> None:
|
||||
"""Test attributes."""
|
||||
await setup_directv_with_locations(hass, client_dtv)
|
||||
await setup_directv_with_locations(hass)
|
||||
|
||||
next_update = mock_now + timedelta(minutes=5)
|
||||
with patch("homeassistant.util.dt.utcnow", return_value=next_update):
|
||||
|
@ -321,10 +283,10 @@ async def test_check_attributes(
|
|||
|
||||
|
||||
async def test_main_services(
|
||||
hass: HomeAssistantType, mock_now: dt_util.dt.datetime, client_dtv: MockDirectvClass
|
||||
hass: HomeAssistantType, mock_now: dt_util.dt.datetime
|
||||
) -> None:
|
||||
"""Test the different services."""
|
||||
await setup_directv_with_locations(hass, client_dtv)
|
||||
await setup_directv(hass)
|
||||
|
||||
next_update = mock_now + timedelta(minutes=5)
|
||||
with patch("homeassistant.util.dt.utcnow", return_value=next_update):
|
||||
|
@ -373,10 +335,10 @@ async def test_main_services(
|
|||
|
||||
|
||||
async def test_available(
|
||||
hass: HomeAssistantType, mock_now: dt_util.dt.datetime, client_dtv: MockDirectvClass
|
||||
hass: HomeAssistantType, mock_now: dt_util.dt.datetime
|
||||
) -> None:
|
||||
"""Test available status."""
|
||||
entry = await setup_directv_with_locations(hass, client_dtv)
|
||||
entry = await setup_directv(hass)
|
||||
|
||||
next_update = mock_now + timedelta(minutes=5)
|
||||
with patch("homeassistant.util.dt.utcnow", return_value=next_update):
|
||||
|
|
Loading…
Reference in New Issue