Cleanup nest async methods that do not need to actually await (#72170)

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
This commit is contained in:
Allen Porter 2022-05-20 07:47:18 -07:00 committed by GitHub
parent d459a5c66e
commit 775be354a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 43 additions and 97 deletions

View file

@ -54,6 +54,7 @@ from . import api, config_flow
from .const import (
CONF_PROJECT_ID,
CONF_SUBSCRIBER_ID,
DATA_DEVICE_MANAGER,
DATA_NEST_CONFIG,
DATA_SDM,
DATA_SUBSCRIBER,
@ -63,8 +64,8 @@ from .events import EVENT_NAME_MAP, NEST_EVENT
from .legacy import async_setup_legacy, async_setup_legacy_entry
from .media_source import (
async_get_media_event_store,
async_get_media_source_devices,
async_get_transcoder,
get_media_source_devices,
)
_LOGGER = logging.getLogger(__name__)
@ -205,7 +206,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
raise ConfigEntryNotReady from err
try:
await subscriber.async_get_device_manager()
device_manager = await subscriber.async_get_device_manager()
except ApiException as err:
if DATA_NEST_UNAVAILABLE not in hass.data[DOMAIN]:
_LOGGER.error("Device manager error: %s", err)
@ -215,6 +216,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass.data[DOMAIN].pop(DATA_NEST_UNAVAILABLE, None)
hass.data[DOMAIN][DATA_SUBSCRIBER] = subscriber
hass.data[DOMAIN][DATA_DEVICE_MANAGER] = device_manager
hass.config_entries.async_setup_platforms(entry, PLATFORMS)
@ -232,6 +234,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if unload_ok:
hass.data[DOMAIN].pop(DATA_SUBSCRIBER)
hass.data[DOMAIN].pop(DATA_DEVICE_MANAGER)
hass.data[DOMAIN].pop(DATA_NEST_UNAVAILABLE, None)
return unload_ok
@ -275,7 +278,7 @@ class NestEventViewBase(HomeAssistantView, ABC):
if not user.permissions.check_entity(entry.entity_id, POLICY_READ):
raise Unauthorized(entity_id=entry.entity_id)
devices = await get_media_source_devices(self.hass)
devices = async_get_media_source_devices(self.hass)
if not (nest_device := devices.get(device_id)):
return self._json_error(
f"No Nest Device found for '{device_id}'", HTTPStatus.NOT_FOUND

View file

@ -15,19 +15,20 @@ from google_nest_sdm.camera_traits import (
StreamingProtocol,
)
from google_nest_sdm.device import Device
from google_nest_sdm.device_manager import DeviceManager
from google_nest_sdm.exceptions import ApiException
from homeassistant.components.camera import Camera, CameraEntityFeature
from homeassistant.components.camera.const import StreamType
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError, PlatformNotReady
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.event import async_track_point_in_utc_time
from homeassistant.util.dt import utcnow
from .const import DATA_SUBSCRIBER, DOMAIN
from .const import DATA_DEVICE_MANAGER, DOMAIN
from .device_info import NestDeviceInfo
_LOGGER = logging.getLogger(__name__)
@ -43,14 +44,7 @@ async def async_setup_sdm_entry(
) -> None:
"""Set up the cameras."""
subscriber = hass.data[DOMAIN][DATA_SUBSCRIBER]
try:
device_manager = await subscriber.async_get_device_manager()
except ApiException as err:
raise PlatformNotReady from err
# Fetch initial data so we have data when entities subscribe.
device_manager: DeviceManager = hass.data[DOMAIN][DATA_DEVICE_MANAGER]
entities = []
for device in device_manager.devices.values():
if (

View file

@ -4,8 +4,8 @@ from __future__ import annotations
from typing import Any, cast
from google_nest_sdm.device import Device
from google_nest_sdm.device_manager import DeviceManager
from google_nest_sdm.device_traits import FanTrait, TemperatureTrait
from google_nest_sdm.exceptions import ApiException
from google_nest_sdm.thermostat_traits import (
ThermostatEcoTrait,
ThermostatHeatCoolTrait,
@ -30,11 +30,10 @@ from homeassistant.components.climate.const import (
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import PlatformNotReady
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DATA_SUBSCRIBER, DOMAIN
from .const import DATA_DEVICE_MANAGER, DOMAIN
from .device_info import NestDeviceInfo
# Mapping for sdm.devices.traits.ThermostatMode mode field
@ -80,12 +79,7 @@ async def async_setup_sdm_entry(
) -> None:
"""Set up the client entities."""
subscriber = hass.data[DOMAIN][DATA_SUBSCRIBER]
try:
device_manager = await subscriber.async_get_device_manager()
except ApiException as err:
raise PlatformNotReady from err
device_manager: DeviceManager = hass.data[DOMAIN][DATA_DEVICE_MANAGER]
entities = []
for device in device_manager.devices.values():
if ThermostatHvacTrait.NAME in device.traits:

View file

@ -3,6 +3,7 @@
DOMAIN = "nest"
DATA_SDM = "sdm"
DATA_SUBSCRIBER = "subscriber"
DATA_DEVICE_MANAGER = "device_manager"
DATA_NEST_CONFIG = "nest_config"
WEB_AUTH_DOMAIN = DOMAIN

View file

@ -1,6 +1,7 @@
"""Provides device automations for Nest."""
from __future__ import annotations
from google_nest_sdm.device_manager import DeviceManager
import voluptuous as vol
from homeassistant.components.automation import (
@ -20,7 +21,7 @@ from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.typing import ConfigType
from .const import DATA_SUBSCRIBER, DOMAIN
from .const import DATA_DEVICE_MANAGER, DOMAIN
from .events import DEVICE_TRAIT_TRIGGER_MAP, NEST_EVENT
DEVICE = "device"
@ -45,14 +46,12 @@ def async_get_nest_device_id(hass: HomeAssistant, device_id: str) -> str | None:
return None
async def async_get_device_trigger_types(
@callback
def async_get_device_trigger_types(
hass: HomeAssistant, nest_device_id: str
) -> list[str]:
"""List event triggers supported for a Nest device."""
# All devices should have already been loaded so any failures here are
# "shouldn't happen" cases
subscriber = hass.data[DOMAIN][DATA_SUBSCRIBER]
device_manager = await subscriber.async_get_device_manager()
device_manager: DeviceManager = hass.data[DOMAIN][DATA_DEVICE_MANAGER]
if not (nest_device := device_manager.devices.get(nest_device_id)):
raise InvalidDeviceAutomationConfig(f"Nest device not found {nest_device_id}")
@ -72,7 +71,7 @@ async def async_get_triggers(
nest_device_id = async_get_nest_device_id(hass, device_id)
if not nest_device_id:
raise InvalidDeviceAutomationConfig(f"Device not found {device_id}")
trigger_types = await async_get_device_trigger_types(hass, nest_device_id)
trigger_types = async_get_device_trigger_types(hass, nest_device_id)
return [
{
CONF_PLATFORM: DEVICE,

View file

@ -6,43 +6,39 @@ from typing import Any
from google_nest_sdm import diagnostics
from google_nest_sdm.device import Device
from google_nest_sdm.device_manager import DeviceManager
from google_nest_sdm.device_traits import InfoTrait
from google_nest_sdm.exceptions import ApiException
from homeassistant.components.camera import diagnostics as camera_diagnostics
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.device_registry import DeviceEntry
from .const import DATA_SDM, DATA_SUBSCRIBER, DOMAIN
from .const import DATA_DEVICE_MANAGER, DATA_SDM, DOMAIN
REDACT_DEVICE_TRAITS = {InfoTrait.NAME}
async def _get_nest_devices(
@callback
def _async_get_nest_devices(
hass: HomeAssistant, config_entry: ConfigEntry
) -> dict[str, Device]:
"""Return dict of available devices."""
if DATA_SDM not in config_entry.data:
return {}
if DATA_SUBSCRIBER not in hass.data[DOMAIN]:
if DATA_DEVICE_MANAGER not in hass.data[DOMAIN]:
return {}
subscriber = hass.data[DOMAIN][DATA_SUBSCRIBER]
device_manager = await subscriber.async_get_device_manager()
devices: dict[str, Device] = device_manager.devices
return devices
device_manager: DeviceManager = hass.data[DOMAIN][DATA_DEVICE_MANAGER]
return device_manager.devices
async def async_get_config_entry_diagnostics(
hass: HomeAssistant, config_entry: ConfigEntry
) -> dict:
"""Return diagnostics for a config entry."""
try:
nest_devices = await _get_nest_devices(hass, config_entry)
except ApiException as err:
return {"error": str(err)}
nest_devices = _async_get_nest_devices(hass, config_entry)
if not nest_devices:
return {}
data: dict[str, Any] = {
@ -65,10 +61,7 @@ async def async_get_device_diagnostics(
device: DeviceEntry,
) -> dict:
"""Return diagnostics for a device."""
try:
nest_devices = await _get_nest_devices(hass, config_entry)
except ApiException as err:
return {"error": str(err)}
nest_devices = _async_get_nest_devices(hass, config_entry)
nest_device_id = next(iter(device.identifiers))[1]
nest_device = nest_devices.get(nest_device_id)
return nest_device.get_diagnostics() if nest_device else {}

View file

@ -25,6 +25,7 @@ import os
from google_nest_sdm.camera_traits import CameraClipPreviewTrait, CameraEventImageTrait
from google_nest_sdm.device import Device
from google_nest_sdm.device_manager import DeviceManager
from google_nest_sdm.event import EventImageType, ImageEventBase
from google_nest_sdm.event_media import (
ClipPreviewSession,
@ -50,13 +51,13 @@ from homeassistant.components.media_source.models import (
MediaSourceItem,
PlayMedia,
)
from homeassistant.core import HomeAssistant
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.storage import Store
from homeassistant.helpers.template import DATE_STR_FORMAT
from homeassistant.util import dt as dt_util
from .const import DATA_SUBSCRIBER, DOMAIN
from .const import DATA_DEVICE_MANAGER, DOMAIN
from .device_info import NestDeviceInfo
from .events import EVENT_NAME_MAP, MEDIA_SOURCE_EVENT_TITLE_MAP
@ -267,13 +268,13 @@ async def async_get_media_source(hass: HomeAssistant) -> MediaSource:
return NestMediaSource(hass)
async def get_media_source_devices(hass: HomeAssistant) -> Mapping[str, Device]:
@callback
def async_get_media_source_devices(hass: HomeAssistant) -> Mapping[str, Device]:
"""Return a mapping of device id to eligible Nest event media devices."""
if DATA_SUBSCRIBER not in hass.data[DOMAIN]:
if DATA_DEVICE_MANAGER not in hass.data[DOMAIN]:
# Integration unloaded, or is legacy nest integration
return {}
subscriber = hass.data[DOMAIN][DATA_SUBSCRIBER]
device_manager = await subscriber.async_get_device_manager()
device_manager: DeviceManager = hass.data[DOMAIN][DATA_DEVICE_MANAGER]
device_registry = dr.async_get(hass)
devices = {}
for device in device_manager.devices.values():
@ -339,7 +340,7 @@ class NestMediaSource(MediaSource):
media_id: MediaId | None = parse_media_id(item.identifier)
if not media_id:
raise Unresolvable("No identifier specified for MediaSourceItem")
devices = await self.devices()
devices = async_get_media_source_devices(self.hass)
if not (device := devices.get(media_id.device_id)):
raise Unresolvable(
"Unable to find device with identifier: %s" % item.identifier
@ -376,7 +377,7 @@ class NestMediaSource(MediaSource):
_LOGGER.debug(
"Browsing media for identifier=%s, media_id=%s", item.identifier, media_id
)
devices = await self.devices()
devices = async_get_media_source_devices(self.hass)
if media_id is None:
# Browse the root and return child devices
browse_root = _browse_root()
@ -443,10 +444,6 @@ class NestMediaSource(MediaSource):
)
return _browse_image_event(media_id, device, single_image)
async def devices(self) -> Mapping[str, Device]:
"""Return all event media related devices."""
return await get_media_source_devices(self.hass)
async def _async_get_clip_preview_sessions(
device: Device,

View file

@ -4,8 +4,8 @@ from __future__ import annotations
import logging
from google_nest_sdm.device import Device
from google_nest_sdm.device_manager import DeviceManager
from google_nest_sdm.device_traits import HumidityTrait, TemperatureTrait
from google_nest_sdm.exceptions import ApiException
from homeassistant.components.sensor import (
SensorDeviceClass,
@ -15,10 +15,9 @@ from homeassistant.components.sensor import (
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import PERCENTAGE, TEMP_CELSIUS
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import PlatformNotReady
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DATA_SUBSCRIBER, DOMAIN
from .const import DATA_DEVICE_MANAGER, DOMAIN
from .device_info import NestDeviceInfo
_LOGGER = logging.getLogger(__name__)
@ -37,13 +36,7 @@ async def async_setup_sdm_entry(
) -> None:
"""Set up the sensors."""
subscriber = hass.data[DOMAIN][DATA_SUBSCRIBER]
try:
device_manager = await subscriber.async_get_device_manager()
except ApiException as err:
_LOGGER.warning("Failed to get devices: %s", err)
raise PlatformNotReady from err
device_manager: DeviceManager = hass.data[DOMAIN][DATA_DEVICE_MANAGER]
entities: list[SensorEntity] = []
for device in device_manager.devices.values():
if TemperatureTrait.NAME in device.traits:

View file

@ -2,7 +2,7 @@
from unittest.mock import patch
from google_nest_sdm.exceptions import ApiException, SubscriberException
from google_nest_sdm.exceptions import SubscriberException
import pytest
from homeassistant.components.nest.const import DOMAIN
@ -139,34 +139,6 @@ async def test_setup_susbcriber_failure(
assert await get_diagnostics_for_config_entry(hass, hass_client, config_entry) == {}
async def test_device_manager_failure(
hass,
hass_client,
config_entry,
setup_platform,
create_device,
):
"""Test configuration error."""
create_device.create(raw_data=DEVICE_API_DATA)
await setup_platform()
assert config_entry.state is ConfigEntryState.LOADED
device_registry = dr.async_get(hass)
device = device_registry.async_get_device({(DOMAIN, NEST_DEVICE_ID)})
assert device is not None
with patch(
"homeassistant.components.nest.diagnostics._get_nest_devices",
side_effect=ApiException("Device manager failure"),
):
assert await get_diagnostics_for_config_entry(
hass, hass_client, config_entry
) == {"error": "Device manager failure"}
assert await get_diagnostics_for_device(
hass, hass_client, config_entry, device
) == {"error": "Device manager failure"}
@pytest.mark.parametrize("nest_test_config", [TEST_CONFIG_LEGACY])
async def test_legacy_config_entry_diagnostics(
hass, hass_client, config_entry, setup_base_platform