Use HassKey in cloud integration (#120322)
parent
b223cb7bb9
commit
ea09d0cbed
|
@ -55,6 +55,7 @@ from .const import (
|
|||
CONF_SERVICEHANDLERS_SERVER,
|
||||
CONF_THINGTALK_SERVER,
|
||||
CONF_USER_POOL_ID,
|
||||
DATA_CLOUD,
|
||||
DATA_PLATFORMS_SETUP,
|
||||
DOMAIN,
|
||||
MODE_DEV,
|
||||
|
@ -155,14 +156,14 @@ def async_is_logged_in(hass: HomeAssistant) -> bool:
|
|||
|
||||
Note: This returns True even if not currently connected to the cloud.
|
||||
"""
|
||||
return DOMAIN in hass.data and hass.data[DOMAIN].is_logged_in
|
||||
return DATA_CLOUD in hass.data and hass.data[DATA_CLOUD].is_logged_in
|
||||
|
||||
|
||||
@bind_hass
|
||||
@callback
|
||||
def async_is_connected(hass: HomeAssistant) -> bool:
|
||||
"""Test if connected to the cloud."""
|
||||
return DOMAIN in hass.data and hass.data[DOMAIN].iot.connected
|
||||
return DATA_CLOUD in hass.data and hass.data[DATA_CLOUD].iot.connected
|
||||
|
||||
|
||||
@callback
|
||||
|
@ -178,7 +179,7 @@ def async_listen_connection_change(
|
|||
@callback
|
||||
def async_active_subscription(hass: HomeAssistant) -> bool:
|
||||
"""Test if user has an active subscription."""
|
||||
return async_is_logged_in(hass) and not hass.data[DOMAIN].subscription_expired
|
||||
return async_is_logged_in(hass) and not hass.data[DATA_CLOUD].subscription_expired
|
||||
|
||||
|
||||
async def async_get_or_create_cloudhook(hass: HomeAssistant, webhook_id: str) -> str:
|
||||
|
@ -189,7 +190,7 @@ async def async_get_or_create_cloudhook(hass: HomeAssistant, webhook_id: str) ->
|
|||
if not async_is_logged_in(hass):
|
||||
raise CloudNotAvailable
|
||||
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
cloudhooks = cloud.client.cloudhooks
|
||||
if hook := cloudhooks.get(webhook_id):
|
||||
return cast(str, hook["cloudhook_url"])
|
||||
|
@ -206,7 +207,7 @@ async def async_create_cloudhook(hass: HomeAssistant, webhook_id: str) -> str:
|
|||
if not async_is_logged_in(hass):
|
||||
raise CloudNotAvailable
|
||||
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
hook = await cloud.cloudhooks.async_create(webhook_id, True)
|
||||
cloudhook_url: str = hook["cloudhook_url"]
|
||||
return cloudhook_url
|
||||
|
@ -215,10 +216,10 @@ async def async_create_cloudhook(hass: HomeAssistant, webhook_id: str) -> str:
|
|||
@bind_hass
|
||||
async def async_delete_cloudhook(hass: HomeAssistant, webhook_id: str) -> None:
|
||||
"""Delete a cloudhook."""
|
||||
if DOMAIN not in hass.data:
|
||||
if DATA_CLOUD not in hass.data:
|
||||
raise CloudNotAvailable
|
||||
|
||||
await hass.data[DOMAIN].cloudhooks.async_delete(webhook_id)
|
||||
await hass.data[DATA_CLOUD].cloudhooks.async_delete(webhook_id)
|
||||
|
||||
|
||||
@bind_hass
|
||||
|
@ -228,10 +229,10 @@ def async_remote_ui_url(hass: HomeAssistant) -> str:
|
|||
if not async_is_logged_in(hass):
|
||||
raise CloudNotAvailable
|
||||
|
||||
if not hass.data[DOMAIN].client.prefs.remote_enabled:
|
||||
if not hass.data[DATA_CLOUD].client.prefs.remote_enabled:
|
||||
raise CloudNotAvailable
|
||||
|
||||
if not (remote_domain := hass.data[DOMAIN].client.prefs.remote_domain):
|
||||
if not (remote_domain := hass.data[DATA_CLOUD].client.prefs.remote_domain):
|
||||
raise CloudNotAvailable
|
||||
|
||||
return f"https://{remote_domain}"
|
||||
|
@ -256,7 +257,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
# Initialize Cloud
|
||||
websession = async_get_clientsession(hass)
|
||||
client = CloudClient(hass, prefs, websession, alexa_conf, google_conf)
|
||||
cloud = hass.data[DOMAIN] = Cloud(client, **kwargs)
|
||||
cloud = hass.data[DATA_CLOUD] = Cloud(client, **kwargs)
|
||||
|
||||
async def _shutdown(event: Event) -> None:
|
||||
"""Shutdown event."""
|
||||
|
@ -373,9 +374,7 @@ def _remote_handle_prefs_updated(cloud: Cloud[CloudClient]) -> None:
|
|||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Set up a config entry."""
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
stt_tts_entities_added: asyncio.Event = hass.data[DATA_PLATFORMS_SETUP][
|
||||
"stt_tts_entities_added"
|
||||
]
|
||||
stt_tts_entities_added = hass.data[DATA_PLATFORMS_SETUP]["stt_tts_entities_added"]
|
||||
stt_tts_entities_added.set()
|
||||
|
||||
return True
|
||||
|
|
|
@ -14,7 +14,7 @@ from homeassistant.const import __version__ as HA_VERSION
|
|||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import config_entry_oauth2_flow, event
|
||||
|
||||
from .const import DOMAIN
|
||||
from .const import DATA_CLOUD, DOMAIN
|
||||
|
||||
DATA_SERVICES = "cloud_account_link_services"
|
||||
CACHE_TIMEOUT = 3600
|
||||
|
@ -68,7 +68,9 @@ async def _get_services(hass: HomeAssistant) -> list[dict[str, Any]]:
|
|||
return services # noqa: RET504
|
||||
|
||||
try:
|
||||
services = await account_link.async_fetch_available_services(hass.data[DOMAIN])
|
||||
services = await account_link.async_fetch_available_services(
|
||||
hass.data[DATA_CLOUD]
|
||||
)
|
||||
except (aiohttp.ClientError, TimeoutError):
|
||||
return []
|
||||
|
||||
|
@ -105,7 +107,7 @@ class CloudOAuth2Implementation(config_entry_oauth2_flow.AbstractOAuth2Implement
|
|||
async def async_generate_authorize_url(self, flow_id: str) -> str:
|
||||
"""Generate a url for the user to authorize."""
|
||||
helper = account_link.AuthorizeAccountHelper(
|
||||
self.hass.data[DOMAIN], self.service
|
||||
self.hass.data[DATA_CLOUD], self.service
|
||||
)
|
||||
authorize_url = await helper.async_get_authorize_url()
|
||||
|
||||
|
@ -138,6 +140,6 @@ class CloudOAuth2Implementation(config_entry_oauth2_flow.AbstractOAuth2Implement
|
|||
async def _async_refresh_token(self, token: dict) -> dict:
|
||||
"""Refresh a token."""
|
||||
new_token = await account_link.async_fetch_access_token(
|
||||
self.hass.data[DOMAIN], self.service, token["refresh_token"]
|
||||
self.hass.data[DATA_CLOUD], self.service, token["refresh_token"]
|
||||
)
|
||||
return {**token, **new_token}
|
||||
|
|
|
@ -27,7 +27,7 @@ async def async_create_cloud_pipeline(hass: HomeAssistant) -> str | None:
|
|||
"""Create a cloud assist pipeline."""
|
||||
# Wait for stt and tts platforms to set up and entities to be added
|
||||
# before creating the pipeline.
|
||||
platforms_setup: dict[str, asyncio.Event] = hass.data[DATA_PLATFORMS_SETUP]
|
||||
platforms_setup = hass.data[DATA_PLATFORMS_SETUP]
|
||||
await asyncio.gather(*(event.wait() for event in platforms_setup.values()))
|
||||
# Make sure the pipeline store is loaded, needed because assist_pipeline
|
||||
# is an after dependency of cloud
|
||||
|
@ -91,7 +91,7 @@ async def async_migrate_cloud_pipeline_engine(
|
|||
else:
|
||||
raise ValueError(f"Invalid platform {platform}")
|
||||
|
||||
platforms_setup: dict[str, asyncio.Event] = hass.data[DATA_PLATFORMS_SETUP]
|
||||
platforms_setup = hass.data[DATA_PLATFORMS_SETUP]
|
||||
await platforms_setup[wait_for_platform].wait()
|
||||
|
||||
# Make sure the pipeline store is loaded, needed because assist_pipeline
|
||||
|
|
|
@ -18,7 +18,7 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
|||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .client import CloudClient
|
||||
from .const import DISPATCHER_REMOTE_UPDATE, DOMAIN
|
||||
from .const import DATA_CLOUD, DISPATCHER_REMOTE_UPDATE
|
||||
|
||||
WAIT_UNTIL_CHANGE = 3
|
||||
|
||||
|
@ -29,7 +29,7 @@ async def async_setup_entry(
|
|||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the Home Assistant Cloud binary sensors."""
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
async_add_entities([CloudRemoteBinary(cloud)])
|
||||
|
||||
|
||||
|
|
|
@ -2,12 +2,22 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
import asyncio
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from homeassistant.util.hass_dict import HassKey
|
||||
from homeassistant.util.signal_type import SignalType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from hass_nabucasa import Cloud
|
||||
|
||||
from .client import CloudClient
|
||||
|
||||
DOMAIN = "cloud"
|
||||
DATA_PLATFORMS_SETUP = "cloud_platforms_setup"
|
||||
DATA_CLOUD: HassKey[Cloud[CloudClient]] = HassKey(DOMAIN)
|
||||
DATA_PLATFORMS_SETUP: HassKey[dict[str, asyncio.Event]] = HassKey(
|
||||
"cloud_platforms_setup"
|
||||
)
|
||||
REQUEST_TIMEOUT = 10
|
||||
|
||||
PREF_ENABLE_ALEXA = "alexa_enabled"
|
||||
|
|
|
@ -38,7 +38,7 @@ from .alexa_config import entity_supported as entity_supported_by_alexa
|
|||
from .assist_pipeline import async_create_cloud_pipeline
|
||||
from .client import CloudClient
|
||||
from .const import (
|
||||
DOMAIN,
|
||||
DATA_CLOUD,
|
||||
PREF_ALEXA_REPORT_STATE,
|
||||
PREF_DISABLE_2FA,
|
||||
PREF_ENABLE_ALEXA,
|
||||
|
@ -196,7 +196,7 @@ class GoogleActionsSyncView(HomeAssistantView):
|
|||
async def post(self, request: web.Request) -> web.Response:
|
||||
"""Trigger a Google Actions sync."""
|
||||
hass = request.app[KEY_HASS]
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
gconf = await cloud.client.get_google_config()
|
||||
status = await gconf.async_sync_entities(gconf.agent_user_id)
|
||||
return self.json({}, status_code=status)
|
||||
|
@ -216,7 +216,7 @@ class CloudLoginView(HomeAssistantView):
|
|||
async def post(self, request: web.Request, data: dict[str, Any]) -> web.Response:
|
||||
"""Handle login request."""
|
||||
hass = request.app[KEY_HASS]
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
await cloud.login(data["email"], data["password"])
|
||||
|
||||
if "assist_pipeline" in hass.config.components:
|
||||
|
@ -237,7 +237,7 @@ class CloudLogoutView(HomeAssistantView):
|
|||
async def post(self, request: web.Request) -> web.Response:
|
||||
"""Handle logout request."""
|
||||
hass = request.app[KEY_HASS]
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
|
||||
async with asyncio.timeout(REQUEST_TIMEOUT):
|
||||
await cloud.logout()
|
||||
|
@ -264,7 +264,7 @@ class CloudRegisterView(HomeAssistantView):
|
|||
async def post(self, request: web.Request, data: dict[str, Any]) -> web.Response:
|
||||
"""Handle registration request."""
|
||||
hass = request.app[KEY_HASS]
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
|
||||
client_metadata = None
|
||||
|
||||
|
@ -301,7 +301,7 @@ class CloudResendConfirmView(HomeAssistantView):
|
|||
async def post(self, request: web.Request, data: dict[str, Any]) -> web.Response:
|
||||
"""Handle resending confirm email code request."""
|
||||
hass = request.app[KEY_HASS]
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
|
||||
async with asyncio.timeout(REQUEST_TIMEOUT):
|
||||
await cloud.auth.async_resend_email_confirm(data["email"])
|
||||
|
@ -321,7 +321,7 @@ class CloudForgotPasswordView(HomeAssistantView):
|
|||
async def post(self, request: web.Request, data: dict[str, Any]) -> web.Response:
|
||||
"""Handle forgot password request."""
|
||||
hass = request.app[KEY_HASS]
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
|
||||
async with asyncio.timeout(REQUEST_TIMEOUT):
|
||||
await cloud.auth.async_forgot_password(data["email"])
|
||||
|
@ -341,7 +341,7 @@ async def websocket_cloud_remove_data(
|
|||
|
||||
Async friendly.
|
||||
"""
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
if cloud.is_logged_in:
|
||||
connection.send_message(
|
||||
websocket_api.error_message(
|
||||
|
@ -367,7 +367,7 @@ async def websocket_cloud_status(
|
|||
|
||||
Async friendly.
|
||||
"""
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
connection.send_message(
|
||||
websocket_api.result_message(msg["id"], await _account_data(hass, cloud))
|
||||
)
|
||||
|
@ -391,7 +391,7 @@ def _require_cloud_login(
|
|||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Require to be logged into the cloud."""
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
if not cloud.is_logged_in:
|
||||
connection.send_message(
|
||||
websocket_api.error_message(
|
||||
|
@ -414,7 +414,7 @@ async def websocket_subscription(
|
|||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Handle request for account info."""
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
if (data := await async_subscription_info(cloud)) is None:
|
||||
connection.send_error(
|
||||
msg["id"], "request_failed", "Failed to request subscription"
|
||||
|
@ -457,7 +457,7 @@ async def websocket_update_prefs(
|
|||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Handle request for account info."""
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
|
||||
changes = dict(msg)
|
||||
changes.pop("id")
|
||||
|
@ -508,7 +508,7 @@ async def websocket_hook_create(
|
|||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Handle request for account info."""
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
hook = await cloud.cloudhooks.async_create(msg["webhook_id"], False)
|
||||
connection.send_message(websocket_api.result_message(msg["id"], hook))
|
||||
|
||||
|
@ -528,7 +528,7 @@ async def websocket_hook_delete(
|
|||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Handle request for account info."""
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
await cloud.cloudhooks.async_delete(msg["webhook_id"])
|
||||
connection.send_message(websocket_api.result_message(msg["id"]))
|
||||
|
||||
|
@ -597,7 +597,7 @@ async def websocket_remote_connect(
|
|||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Handle request for connect remote."""
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
await cloud.client.prefs.async_update(remote_enabled=True)
|
||||
connection.send_result(msg["id"], await _account_data(hass, cloud))
|
||||
|
||||
|
@ -613,7 +613,7 @@ async def websocket_remote_disconnect(
|
|||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Handle request for disconnect remote."""
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
await cloud.client.prefs.async_update(remote_enabled=False)
|
||||
connection.send_result(msg["id"], await _account_data(hass, cloud))
|
||||
|
||||
|
@ -634,7 +634,7 @@ async def google_assistant_get(
|
|||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Get data for a single google assistant entity."""
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
gconf = await cloud.client.get_google_config()
|
||||
entity_id: str = msg["entity_id"]
|
||||
state = hass.states.get(entity_id)
|
||||
|
@ -682,7 +682,7 @@ async def google_assistant_list(
|
|||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""List all google assistant entities."""
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
gconf = await cloud.client.get_google_config()
|
||||
entities = google_helpers.async_get_entities(hass, gconf)
|
||||
|
||||
|
@ -774,7 +774,7 @@ async def alexa_list(
|
|||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""List all alexa entities."""
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
alexa_config = await cloud.client.get_alexa_config()
|
||||
entities = alexa_entities.async_get_entities(hass, alexa_config)
|
||||
|
||||
|
@ -800,7 +800,7 @@ async def alexa_sync(
|
|||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Sync with Alexa."""
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
alexa_config = await cloud.client.get_alexa_config()
|
||||
|
||||
async with asyncio.timeout(10):
|
||||
|
@ -830,7 +830,7 @@ async def thingtalk_convert(
|
|||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Convert a query."""
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
|
||||
async with asyncio.timeout(10):
|
||||
try:
|
||||
|
|
|
@ -5,7 +5,6 @@ from __future__ import annotations
|
|||
import asyncio
|
||||
from typing import Any
|
||||
|
||||
from hass_nabucasa import Cloud
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.repairs import (
|
||||
|
@ -17,8 +16,7 @@ from homeassistant.core import HomeAssistant, callback
|
|||
from homeassistant.data_entry_flow import FlowResult
|
||||
from homeassistant.helpers import issue_registry as ir
|
||||
|
||||
from .client import CloudClient
|
||||
from .const import DOMAIN
|
||||
from .const import DATA_CLOUD, DOMAIN
|
||||
from .subscription import async_migrate_paypal_agreement, async_subscription_info
|
||||
|
||||
BACKOFF_TIME = 5
|
||||
|
@ -73,7 +71,7 @@ class LegacySubscriptionRepairFlow(RepairsFlow):
|
|||
async def async_step_change_plan(self, _: None = None) -> FlowResult:
|
||||
"""Wait for the user to authorize the app installation."""
|
||||
|
||||
cloud: Cloud[CloudClient] = self.hass.data[DOMAIN]
|
||||
cloud = self.hass.data[DATA_CLOUD]
|
||||
|
||||
async def _async_wait_for_plan_change() -> None:
|
||||
flow_manager = repairs_flow_manager(self.hass)
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections.abc import AsyncIterable
|
||||
import logging
|
||||
|
||||
|
@ -28,7 +27,7 @@ from homeassistant.setup import async_when_setup
|
|||
|
||||
from .assist_pipeline import async_migrate_cloud_pipeline_engine
|
||||
from .client import CloudClient
|
||||
from .const import DATA_PLATFORMS_SETUP, DOMAIN, STT_ENTITY_UNIQUE_ID
|
||||
from .const import DATA_CLOUD, DATA_PLATFORMS_SETUP, STT_ENTITY_UNIQUE_ID
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -39,9 +38,9 @@ async def async_setup_entry(
|
|||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up Home Assistant Cloud speech platform via config entry."""
|
||||
stt_platform_loaded: asyncio.Event = hass.data[DATA_PLATFORMS_SETUP][Platform.STT]
|
||||
stt_platform_loaded = hass.data[DATA_PLATFORMS_SETUP][Platform.STT]
|
||||
stt_platform_loaded.set()
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
async_add_entities([CloudProviderEntity(cloud)])
|
||||
|
||||
|
||||
|
|
|
@ -2,13 +2,10 @@
|
|||
|
||||
from typing import Any
|
||||
|
||||
from hass_nabucasa import Cloud
|
||||
|
||||
from homeassistant.components import system_health
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
|
||||
from .client import CloudClient
|
||||
from .const import DOMAIN
|
||||
from .const import DATA_CLOUD
|
||||
|
||||
|
||||
@callback
|
||||
|
@ -21,7 +18,7 @@ def async_register(
|
|||
|
||||
async def system_health_info(hass: HomeAssistant) -> dict[str, Any]:
|
||||
"""Get info for the info page."""
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
client = cloud.client
|
||||
|
||||
data: dict[str, Any] = {
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
|
@ -31,7 +30,7 @@ from homeassistant.setup import async_when_setup
|
|||
|
||||
from .assist_pipeline import async_migrate_cloud_pipeline_engine
|
||||
from .client import CloudClient
|
||||
from .const import DATA_PLATFORMS_SETUP, DOMAIN, TTS_ENTITY_UNIQUE_ID
|
||||
from .const import DATA_CLOUD, DATA_PLATFORMS_SETUP, DOMAIN, TTS_ENTITY_UNIQUE_ID
|
||||
from .prefs import CloudPreferences
|
||||
|
||||
ATTR_GENDER = "gender"
|
||||
|
@ -97,7 +96,7 @@ async def async_get_engine(
|
|||
discovery_info: DiscoveryInfoType | None = None,
|
||||
) -> CloudProvider:
|
||||
"""Set up Cloud speech component."""
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
cloud_provider = CloudProvider(cloud)
|
||||
if discovery_info is not None:
|
||||
discovery_info["platform_loaded"].set()
|
||||
|
@ -110,9 +109,9 @@ async def async_setup_entry(
|
|||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up Home Assistant Cloud text-to-speech platform."""
|
||||
tts_platform_loaded: asyncio.Event = hass.data[DATA_PLATFORMS_SETUP][Platform.TTS]
|
||||
tts_platform_loaded = hass.data[DATA_PLATFORMS_SETUP][Platform.TTS]
|
||||
tts_platform_loaded.set()
|
||||
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
async_add_entities([CloudTTSEntity(cloud)])
|
||||
|
||||
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from hass_nabucasa import Cloud
|
||||
|
||||
from homeassistant.components import cloud
|
||||
from homeassistant.components.cloud import const, prefs as cloud_prefs
|
||||
from homeassistant.components.cloud.const import DATA_CLOUD
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
PIPELINE_DATA = {
|
||||
|
@ -64,7 +63,7 @@ async def mock_cloud(hass, config=None):
|
|||
assert await async_setup_component(hass, "homeassistant", {})
|
||||
|
||||
assert await async_setup_component(hass, cloud.DOMAIN, {"cloud": config or {}})
|
||||
cloud_inst: Cloud = hass.data["cloud"]
|
||||
cloud_inst = hass.data[DATA_CLOUD]
|
||||
with patch("hass_nabucasa.Cloud.run_executor", AsyncMock(return_value=None)):
|
||||
await cloud_inst.initialize()
|
||||
|
||||
|
@ -79,5 +78,5 @@ def mock_cloud_prefs(hass, prefs):
|
|||
const.PREF_GOOGLE_SETTINGS_VERSION: cloud_prefs.GOOGLE_SETTINGS_VERSION,
|
||||
}
|
||||
prefs_to_set.update(prefs)
|
||||
hass.data[cloud.DOMAIN].client._prefs._prefs = prefs_to_set
|
||||
return hass.data[cloud.DOMAIN].client._prefs
|
||||
hass.data[DATA_CLOUD].client._prefs._prefs = prefs_to_set
|
||||
return hass.data[DATA_CLOUD].client._prefs
|
||||
|
|
|
@ -17,7 +17,8 @@ import jwt
|
|||
import pytest
|
||||
from typing_extensions import AsyncGenerator
|
||||
|
||||
from homeassistant.components.cloud import CloudClient, const, prefs
|
||||
from homeassistant.components.cloud import CloudClient, prefs
|
||||
from homeassistant.components.cloud.const import DATA_CLOUD
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util.dt import utcnow
|
||||
|
@ -223,7 +224,7 @@ async def mock_cloud_setup(hass):
|
|||
@pytest.fixture
|
||||
def mock_cloud_login(hass, mock_cloud_setup):
|
||||
"""Mock cloud is logged in."""
|
||||
hass.data[const.DOMAIN].id_token = jwt.encode(
|
||||
hass.data[DATA_CLOUD].id_token = jwt.encode(
|
||||
{
|
||||
"email": "hello@home-assistant.io",
|
||||
"custom:sub-exp": "2300-01-03",
|
||||
|
@ -231,7 +232,7 @@ def mock_cloud_login(hass, mock_cloud_setup):
|
|||
},
|
||||
"test",
|
||||
)
|
||||
with patch.object(hass.data[const.DOMAIN].auth, "async_check_token"):
|
||||
with patch.object(hass.data[DATA_CLOUD].auth, "async_check_token"):
|
||||
yield
|
||||
|
||||
|
||||
|
@ -248,7 +249,7 @@ def mock_auth_fixture():
|
|||
@pytest.fixture
|
||||
def mock_expired_cloud_login(hass, mock_cloud_setup):
|
||||
"""Mock cloud is logged in."""
|
||||
hass.data[const.DOMAIN].id_token = jwt.encode(
|
||||
hass.data[DATA_CLOUD].id_token = jwt.encode(
|
||||
{
|
||||
"email": "hello@home-assistant.io",
|
||||
"custom:sub-exp": "2018-01-01",
|
||||
|
|
|
@ -9,6 +9,7 @@ import pytest
|
|||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.cloud import account_link
|
||||
from homeassistant.components.cloud.const import DATA_CLOUD
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
from homeassistant.helpers import config_entry_oauth2_flow
|
||||
|
@ -133,7 +134,7 @@ async def test_setup_provide_implementation(hass: HomeAssistant) -> None:
|
|||
|
||||
async def test_get_services_cached(hass: HomeAssistant) -> None:
|
||||
"""Test that we cache services."""
|
||||
hass.data["cloud"] = None
|
||||
hass.data[DATA_CLOUD] = None
|
||||
|
||||
services = 1
|
||||
|
||||
|
@ -165,7 +166,7 @@ async def test_get_services_cached(hass: HomeAssistant) -> None:
|
|||
|
||||
async def test_get_services_error(hass: HomeAssistant) -> None:
|
||||
"""Test that we cache services."""
|
||||
hass.data["cloud"] = None
|
||||
hass.data[DATA_CLOUD] = None
|
||||
|
||||
with (
|
||||
patch.object(account_link, "CACHE_TIMEOUT", 0),
|
||||
|
@ -181,7 +182,7 @@ async def test_get_services_error(hass: HomeAssistant) -> None:
|
|||
@pytest.mark.usefixtures("current_request_with_host")
|
||||
async def test_implementation(hass: HomeAssistant, flow_handler) -> None:
|
||||
"""Test Cloud OAuth2 implementation."""
|
||||
hass.data["cloud"] = None
|
||||
hass.data[DATA_CLOUD] = None
|
||||
|
||||
impl = account_link.CloudOAuth2Implementation(hass, "test")
|
||||
assert impl.name == "Home Assistant Cloud"
|
||||
|
|
|
@ -8,6 +8,7 @@ import pytest
|
|||
from homeassistant.components.alexa import errors
|
||||
from homeassistant.components.cloud import ALEXA_SCHEMA, alexa_config
|
||||
from homeassistant.components.cloud.const import (
|
||||
DATA_CLOUD,
|
||||
PREF_ALEXA_DEFAULT_EXPOSE,
|
||||
PREF_ALEXA_ENTITY_CONFIGS,
|
||||
PREF_SHOULD_EXPOSE,
|
||||
|
@ -425,7 +426,7 @@ async def test_alexa_entity_registry_sync(
|
|||
expose_new(hass, True)
|
||||
|
||||
await alexa_config.CloudAlexaConfig(
|
||||
hass, ALEXA_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data["cloud"]
|
||||
hass, ALEXA_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data[DATA_CLOUD]
|
||||
).async_initialize()
|
||||
|
||||
with patch_sync_helper() as (to_update, to_remove):
|
||||
|
@ -506,11 +507,11 @@ def test_enabled_requires_valid_sub(
|
|||
) -> None:
|
||||
"""Test that alexa config enabled requires a valid Cloud sub."""
|
||||
assert cloud_prefs.alexa_enabled
|
||||
assert hass.data["cloud"].is_logged_in
|
||||
assert hass.data["cloud"].subscription_expired
|
||||
assert hass.data[DATA_CLOUD].is_logged_in
|
||||
assert hass.data[DATA_CLOUD].subscription_expired
|
||||
|
||||
config = alexa_config.CloudAlexaConfig(
|
||||
hass, ALEXA_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data["cloud"]
|
||||
hass, ALEXA_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data[DATA_CLOUD]
|
||||
)
|
||||
|
||||
assert not config.enabled
|
||||
|
|
|
@ -15,6 +15,7 @@ from homeassistant.components.cloud.client import (
|
|||
CloudClient,
|
||||
)
|
||||
from homeassistant.components.cloud.const import (
|
||||
DATA_CLOUD,
|
||||
PREF_ALEXA_REPORT_STATE,
|
||||
PREF_ENABLE_ALEXA,
|
||||
PREF_ENABLE_GOOGLE,
|
||||
|
@ -63,7 +64,7 @@ async def test_handler_alexa(hass: HomeAssistant) -> None:
|
|||
)
|
||||
|
||||
mock_cloud_prefs(hass, {PREF_ALEXA_REPORT_STATE: False})
|
||||
cloud = hass.data["cloud"]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
|
||||
resp = await cloud.client.async_alexa_message(
|
||||
test_alexa.get_new_request("Alexa.Discovery", "Discover")
|
||||
|
@ -83,7 +84,7 @@ async def test_handler_alexa(hass: HomeAssistant) -> None:
|
|||
async def test_handler_alexa_disabled(hass: HomeAssistant, mock_cloud_fixture) -> None:
|
||||
"""Test handler Alexa when user has disabled it."""
|
||||
mock_cloud_fixture._prefs[PREF_ENABLE_ALEXA] = False
|
||||
cloud = hass.data["cloud"]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
|
||||
resp = await cloud.client.async_alexa_message(
|
||||
test_alexa.get_new_request("Alexa.Discovery", "Discover")
|
||||
|
@ -117,7 +118,7 @@ async def test_handler_google_actions(hass: HomeAssistant) -> None:
|
|||
)
|
||||
|
||||
mock_cloud_prefs(hass, {})
|
||||
cloud = hass.data["cloud"]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
|
||||
reqid = "5711642932632160983"
|
||||
data = {"requestId": reqid, "inputs": [{"intent": "action.devices.SYNC"}]}
|
||||
|
@ -164,7 +165,7 @@ async def test_handler_google_actions_disabled(
|
|||
reqid = "5711642932632160983"
|
||||
data = {"requestId": reqid, "inputs": [{"intent": intent}]}
|
||||
|
||||
cloud = hass.data["cloud"]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
with patch(
|
||||
"hass_nabucasa.Cloud._decode_claims",
|
||||
return_value={"cognito:username": "myUserName"},
|
||||
|
@ -182,7 +183,7 @@ async def test_webhook_msg(
|
|||
with patch("hass_nabucasa.Cloud.initialize"):
|
||||
setup = await async_setup_component(hass, "cloud", {"cloud": {}})
|
||||
assert setup
|
||||
cloud = hass.data["cloud"]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
|
||||
await cloud.client.prefs.async_initialize()
|
||||
await cloud.client.prefs.async_update(
|
||||
|
@ -269,7 +270,7 @@ async def test_google_config_expose_entity(
|
|||
"light", "test", "unique", suggested_object_id="kitchen"
|
||||
)
|
||||
|
||||
cloud_client = hass.data[DOMAIN].client
|
||||
cloud_client = hass.data[DATA_CLOUD].client
|
||||
state = State(entity_entry.entity_id, "on")
|
||||
gconf = await cloud_client.get_google_config()
|
||||
|
||||
|
@ -293,7 +294,7 @@ async def test_google_config_should_2fa(
|
|||
"light", "test", "unique", suggested_object_id="kitchen"
|
||||
)
|
||||
|
||||
cloud_client = hass.data[DOMAIN].client
|
||||
cloud_client = hass.data[DATA_CLOUD].client
|
||||
gconf = await cloud_client.get_google_config()
|
||||
state = State(entity_entry.entity_id, "on")
|
||||
|
||||
|
@ -350,7 +351,7 @@ async def test_system_msg(hass: HomeAssistant) -> None:
|
|||
with patch("hass_nabucasa.Cloud.initialize"):
|
||||
setup = await async_setup_component(hass, "cloud", {"cloud": {}})
|
||||
assert setup
|
||||
cloud = hass.data["cloud"]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
|
||||
assert cloud.client.relayer_region is None
|
||||
|
||||
|
@ -373,7 +374,7 @@ async def test_cloud_connection_info(hass: HomeAssistant) -> None:
|
|||
hexmock.return_value = "12345678901234567890"
|
||||
setup = await async_setup_component(hass, "cloud", {"cloud": {}})
|
||||
assert setup
|
||||
cloud = hass.data["cloud"]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
|
||||
response = await cloud.client.async_cloud_connection_info({})
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import pytest
|
|||
|
||||
from homeassistant.components.cloud import GACTIONS_SCHEMA
|
||||
from homeassistant.components.cloud.const import (
|
||||
DATA_CLOUD,
|
||||
PREF_DISABLE_2FA,
|
||||
PREF_GOOGLE_DEFAULT_EXPOSE,
|
||||
PREF_GOOGLE_ENTITY_CONFIGS,
|
||||
|
@ -196,7 +197,7 @@ async def test_google_entity_registry_sync(
|
|||
expose_new(hass, True)
|
||||
|
||||
config = CloudGoogleConfig(
|
||||
hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data["cloud"]
|
||||
hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data[DATA_CLOUD]
|
||||
)
|
||||
await config.async_initialize()
|
||||
await config.async_connect_agent_user("mock-user-id")
|
||||
|
@ -264,7 +265,7 @@ async def test_google_device_registry_sync(
|
|||
) -> None:
|
||||
"""Test Google config responds to device registry."""
|
||||
config = CloudGoogleConfig(
|
||||
hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data["cloud"]
|
||||
hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data[DATA_CLOUD]
|
||||
)
|
||||
|
||||
# Enable exposing new entities to Google
|
||||
|
@ -333,7 +334,7 @@ async def test_sync_google_when_started(
|
|||
) -> None:
|
||||
"""Test Google config syncs on init."""
|
||||
config = CloudGoogleConfig(
|
||||
hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data["cloud"]
|
||||
hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data[DATA_CLOUD]
|
||||
)
|
||||
with patch.object(config, "async_sync_entities_all") as mock_sync:
|
||||
await config.async_initialize()
|
||||
|
@ -346,7 +347,7 @@ async def test_sync_google_on_home_assistant_start(
|
|||
) -> None:
|
||||
"""Test Google config syncs when home assistant started."""
|
||||
config = CloudGoogleConfig(
|
||||
hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data["cloud"]
|
||||
hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data[DATA_CLOUD]
|
||||
)
|
||||
hass.set_state(CoreState.not_running)
|
||||
with patch.object(config, "async_sync_entities_all") as mock_sync:
|
||||
|
@ -441,11 +442,11 @@ def test_enabled_requires_valid_sub(
|
|||
) -> None:
|
||||
"""Test that google config enabled requires a valid Cloud sub."""
|
||||
assert cloud_prefs.google_enabled
|
||||
assert hass.data["cloud"].is_logged_in
|
||||
assert hass.data["cloud"].subscription_expired
|
||||
assert hass.data[DATA_CLOUD].is_logged_in
|
||||
assert hass.data[DATA_CLOUD].subscription_expired
|
||||
|
||||
config = CloudGoogleConfig(
|
||||
hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data["cloud"]
|
||||
hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data[DATA_CLOUD]
|
||||
)
|
||||
|
||||
assert not config.enabled
|
||||
|
@ -494,7 +495,7 @@ async def test_google_handle_logout(
|
|||
await cloud_prefs.get_cloud_user()
|
||||
|
||||
with patch.object(
|
||||
hass.data["cloud"].auth,
|
||||
hass.data[DATA_CLOUD].auth,
|
||||
"async_check_token",
|
||||
side_effect=AssertionError("Should not be called"),
|
||||
):
|
||||
|
@ -857,7 +858,7 @@ async def test_google_config_get_agent_user_id(
|
|||
) -> None:
|
||||
"""Test overridden get_agent_user_id_from_webhook method."""
|
||||
config = CloudGoogleConfig(
|
||||
hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data["cloud"]
|
||||
hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data[DATA_CLOUD]
|
||||
)
|
||||
assert (
|
||||
config.get_agent_user_id_from_webhook(cloud_prefs.google_local_webhook_id)
|
||||
|
|
|
@ -4,7 +4,6 @@ from collections.abc import Callable, Coroutine
|
|||
from typing import Any
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from hass_nabucasa import Cloud
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import cloud
|
||||
|
@ -13,7 +12,7 @@ from homeassistant.components.cloud import (
|
|||
CloudNotConnected,
|
||||
async_get_or_create_cloudhook,
|
||||
)
|
||||
from homeassistant.components.cloud.const import DOMAIN, PREF_CLOUDHOOKS
|
||||
from homeassistant.components.cloud.const import DATA_CLOUD, DOMAIN, PREF_CLOUDHOOKS
|
||||
from homeassistant.components.cloud.prefs import STORAGE_KEY
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
|
||||
from homeassistant.core import Context, HomeAssistant
|
||||
|
@ -47,7 +46,7 @@ async def test_constructor_loads_info_from_config(hass: HomeAssistant) -> None:
|
|||
)
|
||||
assert result
|
||||
|
||||
cl = hass.data["cloud"]
|
||||
cl = hass.data[DATA_CLOUD]
|
||||
assert cl.mode == cloud.MODE_DEV
|
||||
assert cl.cognito_client_id == "test-cognito_client_id"
|
||||
assert cl.user_pool_id == "test-user_pool_id"
|
||||
|
@ -65,7 +64,7 @@ async def test_remote_services(
|
|||
hass: HomeAssistant, mock_cloud_fixture, hass_read_only_user: MockUser
|
||||
) -> None:
|
||||
"""Setup cloud component and test services."""
|
||||
cloud = hass.data[DOMAIN]
|
||||
cloud = hass.data[DATA_CLOUD]
|
||||
|
||||
assert hass.services.has_service(DOMAIN, "remote_connect")
|
||||
assert hass.services.has_service(DOMAIN, "remote_disconnect")
|
||||
|
@ -145,7 +144,7 @@ async def test_setup_existing_cloud_user(
|
|||
|
||||
async def test_on_connect(hass: HomeAssistant, mock_cloud_fixture) -> None:
|
||||
"""Test cloud on connect triggers."""
|
||||
cl: Cloud[cloud.client.CloudClient] = hass.data["cloud"]
|
||||
cl = hass.data[DATA_CLOUD]
|
||||
|
||||
assert len(cl.iot._on_connect) == 3
|
||||
|
||||
|
@ -202,7 +201,7 @@ async def test_on_connect(hass: HomeAssistant, mock_cloud_fixture) -> None:
|
|||
|
||||
async def test_remote_ui_url(hass: HomeAssistant, mock_cloud_fixture) -> None:
|
||||
"""Test getting remote ui url."""
|
||||
cl = hass.data["cloud"]
|
||||
cl = hass.data[DATA_CLOUD]
|
||||
|
||||
# Not logged in
|
||||
with pytest.raises(cloud.CloudNotAvailable):
|
||||
|
|
Loading…
Reference in New Issue