Allow exposing domains in cloud (#39216)
parent
414a59ae9f
commit
5217139e0b
|
@ -14,18 +14,13 @@ from homeassistant.components.alexa import (
|
|||
state_report as alexa_state_report,
|
||||
)
|
||||
from homeassistant.const import CLOUD_NEVER_EXPOSED_ENTITIES, HTTP_BAD_REQUEST
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.core import callback, split_entity_id
|
||||
from homeassistant.helpers import entity_registry
|
||||
from homeassistant.helpers.event import async_call_later
|
||||
from homeassistant.util.dt import utcnow
|
||||
|
||||
from .const import (
|
||||
CONF_ENTITY_CONFIG,
|
||||
CONF_FILTER,
|
||||
DEFAULT_SHOULD_EXPOSE,
|
||||
PREF_SHOULD_EXPOSE,
|
||||
RequireRelink,
|
||||
)
|
||||
from .const import CONF_ENTITY_CONFIG, CONF_FILTER, PREF_SHOULD_EXPOSE, RequireRelink
|
||||
from .prefs import CloudPreferences
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -37,7 +32,7 @@ SYNC_DELAY = 1
|
|||
class AlexaConfig(alexa_config.AbstractConfig):
|
||||
"""Alexa Configuration."""
|
||||
|
||||
def __init__(self, hass, config, prefs, cloud):
|
||||
def __init__(self, hass, config, prefs: CloudPreferences, cloud):
|
||||
"""Initialize the Alexa config."""
|
||||
super().__init__(hass)
|
||||
self._config = config
|
||||
|
@ -46,6 +41,7 @@ class AlexaConfig(alexa_config.AbstractConfig):
|
|||
self._token = None
|
||||
self._token_valid = None
|
||||
self._cur_entity_prefs = prefs.alexa_entity_configs
|
||||
self._cur_default_expose = prefs.alexa_default_expose
|
||||
self._alexa_sync_unsub = None
|
||||
self._endpoint = None
|
||||
|
||||
|
@ -99,7 +95,17 @@ class AlexaConfig(alexa_config.AbstractConfig):
|
|||
|
||||
entity_configs = self._prefs.alexa_entity_configs
|
||||
entity_config = entity_configs.get(entity_id, {})
|
||||
return entity_config.get(PREF_SHOULD_EXPOSE, DEFAULT_SHOULD_EXPOSE)
|
||||
entity_expose = entity_config.get(PREF_SHOULD_EXPOSE)
|
||||
if entity_expose is not None:
|
||||
return entity_expose
|
||||
|
||||
default_expose = self._prefs.alexa_default_expose
|
||||
|
||||
# Backwards compat
|
||||
if default_expose is None:
|
||||
return True
|
||||
|
||||
return split_entity_id(entity_id)[0] in default_expose
|
||||
|
||||
@callback
|
||||
def async_invalidate_access_token(self):
|
||||
|
@ -147,16 +153,24 @@ class AlexaConfig(alexa_config.AbstractConfig):
|
|||
await self.async_sync_entities()
|
||||
return
|
||||
|
||||
# If entity prefs are the same or we have filter in config.yaml,
|
||||
# don't sync.
|
||||
# If user has filter in config.yaml, don't sync.
|
||||
if not self._config[CONF_FILTER].empty_filter:
|
||||
return
|
||||
|
||||
# If entity prefs are the same, don't sync.
|
||||
if (
|
||||
self._cur_entity_prefs is prefs.alexa_entity_configs
|
||||
or not self._config[CONF_FILTER].empty_filter
|
||||
and self._cur_default_expose is prefs.alexa_default_expose
|
||||
):
|
||||
return
|
||||
|
||||
if self._alexa_sync_unsub:
|
||||
self._alexa_sync_unsub()
|
||||
self._alexa_sync_unsub = None
|
||||
|
||||
if self._cur_default_expose is not prefs.alexa_default_expose:
|
||||
await self.async_sync_entities()
|
||||
return
|
||||
|
||||
self._alexa_sync_unsub = async_call_later(
|
||||
self.hass, SYNC_DELAY, self._sync_prefs
|
||||
|
|
|
@ -18,10 +18,25 @@ PREF_ALIASES = "aliases"
|
|||
PREF_SHOULD_EXPOSE = "should_expose"
|
||||
PREF_GOOGLE_LOCAL_WEBHOOK_ID = "google_local_webhook_id"
|
||||
PREF_USERNAME = "username"
|
||||
DEFAULT_SHOULD_EXPOSE = True
|
||||
PREF_ALEXA_DEFAULT_EXPOSE = "alexa_default_expose"
|
||||
PREF_GOOGLE_DEFAULT_EXPOSE = "google_default_expose"
|
||||
DEFAULT_DISABLE_2FA = False
|
||||
DEFAULT_ALEXA_REPORT_STATE = False
|
||||
DEFAULT_GOOGLE_REPORT_STATE = False
|
||||
DEFAULT_EXPOSED_DOMAINS = [
|
||||
"climate",
|
||||
"cover",
|
||||
"fan",
|
||||
"humidifier",
|
||||
"light",
|
||||
"lock",
|
||||
"scene",
|
||||
"script",
|
||||
"sensor",
|
||||
"switch",
|
||||
"vacuum",
|
||||
"water_heater",
|
||||
]
|
||||
|
||||
CONF_ALEXA = "alexa"
|
||||
CONF_ALIASES = "aliases"
|
||||
|
|
|
@ -11,16 +11,16 @@ from homeassistant.const import (
|
|||
EVENT_HOMEASSISTANT_STARTED,
|
||||
HTTP_OK,
|
||||
)
|
||||
from homeassistant.core import CoreState, callback
|
||||
from homeassistant.core import CoreState, callback, split_entity_id
|
||||
from homeassistant.helpers import entity_registry
|
||||
|
||||
from .const import (
|
||||
CONF_ENTITY_CONFIG,
|
||||
DEFAULT_DISABLE_2FA,
|
||||
DEFAULT_SHOULD_EXPOSE,
|
||||
PREF_DISABLE_2FA,
|
||||
PREF_SHOULD_EXPOSE,
|
||||
)
|
||||
from .prefs import CloudPreferences
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -28,7 +28,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||
class CloudGoogleConfig(AbstractConfig):
|
||||
"""HA Cloud Configuration for Google Assistant."""
|
||||
|
||||
def __init__(self, hass, config, cloud_user, prefs, cloud):
|
||||
def __init__(self, hass, config, cloud_user, prefs: CloudPreferences, cloud):
|
||||
"""Initialize the Google config."""
|
||||
super().__init__(hass)
|
||||
self._config = config
|
||||
|
@ -36,6 +36,7 @@ class CloudGoogleConfig(AbstractConfig):
|
|||
self._prefs = prefs
|
||||
self._cloud = cloud
|
||||
self._cur_entity_prefs = self._prefs.google_entity_configs
|
||||
self._cur_default_expose = self._prefs.google_default_expose
|
||||
self._sync_entities_lock = asyncio.Lock()
|
||||
self._sync_on_started = False
|
||||
|
||||
|
@ -104,7 +105,17 @@ class CloudGoogleConfig(AbstractConfig):
|
|||
|
||||
entity_configs = self._prefs.google_entity_configs
|
||||
entity_config = entity_configs.get(entity_id, {})
|
||||
return entity_config.get(PREF_SHOULD_EXPOSE, DEFAULT_SHOULD_EXPOSE)
|
||||
entity_expose = entity_config.get(PREF_SHOULD_EXPOSE)
|
||||
if entity_expose is not None:
|
||||
return entity_expose
|
||||
|
||||
default_expose = self._prefs.google_default_expose
|
||||
|
||||
# Backwards compat
|
||||
if default_expose is None:
|
||||
return True
|
||||
|
||||
return split_entity_id(entity_id)[0] in default_expose
|
||||
|
||||
@property
|
||||
def agent_user_id(self):
|
||||
|
@ -153,8 +164,8 @@ class CloudGoogleConfig(AbstractConfig):
|
|||
# don't sync.
|
||||
elif (
|
||||
self._cur_entity_prefs is not prefs.google_entity_configs
|
||||
and self._config["filter"].empty_filter
|
||||
):
|
||||
or self._cur_default_expose is not prefs.google_default_expose
|
||||
) and self._config["filter"].empty_filter:
|
||||
self.async_schedule_google_sync_all()
|
||||
|
||||
if self.enabled and not self.is_local_sdk_active:
|
||||
|
@ -162,6 +173,9 @@ class CloudGoogleConfig(AbstractConfig):
|
|||
elif not self.enabled and self.is_local_sdk_active:
|
||||
self.async_disable_local_sdk()
|
||||
|
||||
self._cur_entity_prefs = prefs.google_entity_configs
|
||||
self._cur_default_expose = prefs.google_default_expose
|
||||
|
||||
async def _handle_entity_registry_updated(self, event):
|
||||
"""Handle when entity registry updated."""
|
||||
if not self.enabled or not self._cloud.is_logged_in:
|
||||
|
|
|
@ -24,9 +24,11 @@ from homeassistant.core import callback
|
|||
|
||||
from .const import (
|
||||
DOMAIN,
|
||||
PREF_ALEXA_DEFAULT_EXPOSE,
|
||||
PREF_ALEXA_REPORT_STATE,
|
||||
PREF_ENABLE_ALEXA,
|
||||
PREF_ENABLE_GOOGLE,
|
||||
PREF_GOOGLE_DEFAULT_EXPOSE,
|
||||
PREF_GOOGLE_REPORT_STATE,
|
||||
PREF_GOOGLE_SECURE_DEVICES_PIN,
|
||||
REQUEST_TIMEOUT,
|
||||
|
@ -371,6 +373,8 @@ async def websocket_subscription(hass, connection, msg):
|
|||
vol.Optional(PREF_ENABLE_ALEXA): bool,
|
||||
vol.Optional(PREF_ALEXA_REPORT_STATE): bool,
|
||||
vol.Optional(PREF_GOOGLE_REPORT_STATE): bool,
|
||||
vol.Optional(PREF_ALEXA_DEFAULT_EXPOSE): [str],
|
||||
vol.Optional(PREF_GOOGLE_DEFAULT_EXPOSE): [str],
|
||||
vol.Optional(PREF_GOOGLE_SECURE_DEVICES_PIN): vol.Any(None, str),
|
||||
}
|
||||
)
|
||||
|
@ -514,7 +518,7 @@ async def google_assistant_list(hass, connection, msg):
|
|||
{
|
||||
"type": "cloud/google_assistant/entities/update",
|
||||
"entity_id": str,
|
||||
vol.Optional("should_expose"): bool,
|
||||
vol.Optional("should_expose"): vol.Any(None, bool),
|
||||
vol.Optional("override_name"): str,
|
||||
vol.Optional("aliases"): [str],
|
||||
vol.Optional("disable_2fa"): bool,
|
||||
|
@ -566,7 +570,7 @@ async def alexa_list(hass, connection, msg):
|
|||
{
|
||||
"type": "cloud/alexa/entities/update",
|
||||
"entity_id": str,
|
||||
vol.Optional("should_expose"): bool,
|
||||
vol.Optional("should_expose"): vol.Any(None, bool),
|
||||
}
|
||||
)
|
||||
async def alexa_update(hass, connection, msg):
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"""Preference management for cloud."""
|
||||
from ipaddress import ip_address
|
||||
from typing import Optional
|
||||
from typing import List, Optional
|
||||
|
||||
from homeassistant.auth.const import GROUP_ID_ADMIN
|
||||
from homeassistant.auth.models import User
|
||||
|
@ -9,8 +9,10 @@ from homeassistant.util.logging import async_create_catching_coro
|
|||
|
||||
from .const import (
|
||||
DEFAULT_ALEXA_REPORT_STATE,
|
||||
DEFAULT_EXPOSED_DOMAINS,
|
||||
DEFAULT_GOOGLE_REPORT_STATE,
|
||||
DOMAIN,
|
||||
PREF_ALEXA_DEFAULT_EXPOSE,
|
||||
PREF_ALEXA_ENTITY_CONFIGS,
|
||||
PREF_ALEXA_REPORT_STATE,
|
||||
PREF_ALIASES,
|
||||
|
@ -20,6 +22,7 @@ from .const import (
|
|||
PREF_ENABLE_ALEXA,
|
||||
PREF_ENABLE_GOOGLE,
|
||||
PREF_ENABLE_REMOTE,
|
||||
PREF_GOOGLE_DEFAULT_EXPOSE,
|
||||
PREF_GOOGLE_ENTITY_CONFIGS,
|
||||
PREF_GOOGLE_LOCAL_WEBHOOK_ID,
|
||||
PREF_GOOGLE_REPORT_STATE,
|
||||
|
@ -81,6 +84,8 @@ class CloudPreferences:
|
|||
alexa_entity_configs=_UNDEF,
|
||||
alexa_report_state=_UNDEF,
|
||||
google_report_state=_UNDEF,
|
||||
alexa_default_expose=_UNDEF,
|
||||
google_default_expose=_UNDEF,
|
||||
):
|
||||
"""Update user preferences."""
|
||||
prefs = {**self._prefs}
|
||||
|
@ -96,6 +101,8 @@ class CloudPreferences:
|
|||
(PREF_ALEXA_ENTITY_CONFIGS, alexa_entity_configs),
|
||||
(PREF_ALEXA_REPORT_STATE, alexa_report_state),
|
||||
(PREF_GOOGLE_REPORT_STATE, google_report_state),
|
||||
(PREF_ALEXA_DEFAULT_EXPOSE, alexa_default_expose),
|
||||
(PREF_GOOGLE_DEFAULT_EXPOSE, google_default_expose),
|
||||
):
|
||||
if value is not _UNDEF:
|
||||
prefs[key] = value
|
||||
|
@ -185,15 +192,17 @@ class CloudPreferences:
|
|||
def as_dict(self):
|
||||
"""Return dictionary version."""
|
||||
return {
|
||||
PREF_ALEXA_DEFAULT_EXPOSE: self.alexa_default_expose,
|
||||
PREF_ALEXA_ENTITY_CONFIGS: self.alexa_entity_configs,
|
||||
PREF_ALEXA_REPORT_STATE: self.alexa_report_state,
|
||||
PREF_CLOUDHOOKS: self.cloudhooks,
|
||||
PREF_ENABLE_ALEXA: self.alexa_enabled,
|
||||
PREF_ENABLE_GOOGLE: self.google_enabled,
|
||||
PREF_ENABLE_REMOTE: self.remote_enabled,
|
||||
PREF_GOOGLE_SECURE_DEVICES_PIN: self.google_secure_devices_pin,
|
||||
PREF_GOOGLE_DEFAULT_EXPOSE: self.google_default_expose,
|
||||
PREF_GOOGLE_ENTITY_CONFIGS: self.google_entity_configs,
|
||||
PREF_ALEXA_ENTITY_CONFIGS: self.alexa_entity_configs,
|
||||
PREF_ALEXA_REPORT_STATE: self.alexa_report_state,
|
||||
PREF_GOOGLE_REPORT_STATE: self.google_report_state,
|
||||
PREF_CLOUDHOOKS: self.cloudhooks,
|
||||
PREF_GOOGLE_SECURE_DEVICES_PIN: self.google_secure_devices_pin,
|
||||
}
|
||||
|
||||
@property
|
||||
|
@ -219,6 +228,19 @@ class CloudPreferences:
|
|||
"""Return if Alexa report state is enabled."""
|
||||
return self._prefs.get(PREF_ALEXA_REPORT_STATE, DEFAULT_ALEXA_REPORT_STATE)
|
||||
|
||||
@property
|
||||
def alexa_default_expose(self) -> Optional[List[str]]:
|
||||
"""Return array of entity domains that are exposed by default to Alexa.
|
||||
|
||||
Can return None, in which case for backwards should be interpreted as allow all domains.
|
||||
"""
|
||||
return self._prefs.get(PREF_ALEXA_DEFAULT_EXPOSE)
|
||||
|
||||
@property
|
||||
def alexa_entity_configs(self):
|
||||
"""Return Alexa Entity configurations."""
|
||||
return self._prefs.get(PREF_ALEXA_ENTITY_CONFIGS, {})
|
||||
|
||||
@property
|
||||
def google_enabled(self):
|
||||
"""Return if Google is enabled."""
|
||||
|
@ -245,9 +267,12 @@ class CloudPreferences:
|
|||
return self._prefs[PREF_GOOGLE_LOCAL_WEBHOOK_ID]
|
||||
|
||||
@property
|
||||
def alexa_entity_configs(self):
|
||||
"""Return Alexa Entity configurations."""
|
||||
return self._prefs.get(PREF_ALEXA_ENTITY_CONFIGS, {})
|
||||
def google_default_expose(self) -> Optional[List[str]]:
|
||||
"""Return array of entity domains that are exposed by default to Google.
|
||||
|
||||
Can return None, in which case for backwards should be interpreted as allow all domains.
|
||||
"""
|
||||
return self._prefs.get(PREF_GOOGLE_DEFAULT_EXPOSE)
|
||||
|
||||
@property
|
||||
def cloudhooks(self):
|
||||
|
@ -322,14 +347,16 @@ class CloudPreferences:
|
|||
def _empty_config(self, username):
|
||||
"""Return an empty config."""
|
||||
return {
|
||||
PREF_ALEXA_DEFAULT_EXPOSE: DEFAULT_EXPOSED_DOMAINS,
|
||||
PREF_ALEXA_ENTITY_CONFIGS: {},
|
||||
PREF_CLOUD_USER: None,
|
||||
PREF_CLOUDHOOKS: {},
|
||||
PREF_ENABLE_ALEXA: True,
|
||||
PREF_ENABLE_GOOGLE: True,
|
||||
PREF_ENABLE_REMOTE: False,
|
||||
PREF_GOOGLE_SECURE_DEVICES_PIN: None,
|
||||
PREF_GOOGLE_DEFAULT_EXPOSE: DEFAULT_EXPOSED_DOMAINS,
|
||||
PREF_GOOGLE_ENTITY_CONFIGS: {},
|
||||
PREF_ALEXA_ENTITY_CONFIGS: {},
|
||||
PREF_CLOUDHOOKS: {},
|
||||
PREF_CLOUD_USER: None,
|
||||
PREF_USERNAME: username,
|
||||
PREF_GOOGLE_LOCAL_WEBHOOK_ID: self._hass.components.webhook.async_generate_id(),
|
||||
PREF_GOOGLE_SECURE_DEVICES_PIN: None,
|
||||
PREF_USERNAME: username,
|
||||
}
|
||||
|
|
|
@ -12,13 +12,22 @@ from tests.common import async_fire_time_changed
|
|||
async def test_alexa_config_expose_entity_prefs(hass, cloud_prefs):
|
||||
"""Test Alexa config should expose using prefs."""
|
||||
entity_conf = {"should_expose": False}
|
||||
await cloud_prefs.async_update(alexa_entity_configs={"light.kitchen": entity_conf})
|
||||
await cloud_prefs.async_update(
|
||||
alexa_entity_configs={"light.kitchen": entity_conf},
|
||||
alexa_default_expose=["light"],
|
||||
)
|
||||
conf = alexa_config.AlexaConfig(hass, ALEXA_SCHEMA({}), cloud_prefs, None)
|
||||
|
||||
assert not conf.should_expose("light.kitchen")
|
||||
entity_conf["should_expose"] = True
|
||||
assert conf.should_expose("light.kitchen")
|
||||
|
||||
entity_conf["should_expose"] = None
|
||||
assert conf.should_expose("light.kitchen")
|
||||
|
||||
await cloud_prefs.async_update(alexa_default_expose=["sensor"],)
|
||||
assert not conf.should_expose("light.kitchen")
|
||||
|
||||
|
||||
async def test_alexa_config_report_state(hass, cloud_prefs):
|
||||
"""Test Alexa config should expose using prefs."""
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
"""Test the Cloud Google Config."""
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.cloud import GACTIONS_SCHEMA
|
||||
from homeassistant.components.cloud.google_config import CloudGoogleConfig
|
||||
from homeassistant.components.google_assistant import helpers as ga_helpers
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_STARTED, HTTP_NOT_FOUND
|
||||
from homeassistant.core import CoreState
|
||||
from homeassistant.core import CoreState, State
|
||||
from homeassistant.helpers.entity_registry import EVENT_ENTITY_REGISTRY_UPDATED
|
||||
from homeassistant.util.dt import utcnow
|
||||
|
||||
|
@ -11,19 +13,24 @@ from tests.async_mock import AsyncMock, Mock, patch
|
|||
from tests.common import async_fire_time_changed
|
||||
|
||||
|
||||
async def test_google_update_report_state(hass, cloud_prefs):
|
||||
"""Test Google config responds to updating preference."""
|
||||
config = CloudGoogleConfig(
|
||||
@pytest.fixture
|
||||
def mock_conf(hass, cloud_prefs):
|
||||
"""Mock Google conf."""
|
||||
return CloudGoogleConfig(
|
||||
hass,
|
||||
GACTIONS_SCHEMA({}),
|
||||
"mock-user-id",
|
||||
cloud_prefs,
|
||||
Mock(claims={"cognito:username": "abcdefghjkl"}),
|
||||
)
|
||||
await config.async_initialize()
|
||||
await config.async_connect_agent_user("mock-user-id")
|
||||
|
||||
with patch.object(config, "async_sync_entities") as mock_sync, patch(
|
||||
|
||||
async def test_google_update_report_state(mock_conf, hass, cloud_prefs):
|
||||
"""Test Google config responds to updating preference."""
|
||||
await mock_conf.async_initialize()
|
||||
await mock_conf.async_connect_agent_user("mock-user-id")
|
||||
|
||||
with patch.object(mock_conf, "async_sync_entities") as mock_sync, patch(
|
||||
"homeassistant.components.google_assistant.report_state.async_enable_report_state"
|
||||
) as mock_report_state:
|
||||
await cloud_prefs.async_update(google_report_state=True)
|
||||
|
@ -161,3 +168,24 @@ async def test_google_entity_registry_sync(hass, mock_cloud_login, cloud_prefs):
|
|||
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
|
||||
await hass.async_block_till_done()
|
||||
assert len(mock_sync.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_google_config_expose_entity_prefs(mock_conf, cloud_prefs):
|
||||
"""Test Google config should expose using prefs."""
|
||||
entity_conf = {"should_expose": False}
|
||||
await cloud_prefs.async_update(
|
||||
google_entity_configs={"light.kitchen": entity_conf},
|
||||
google_default_expose=["light"],
|
||||
)
|
||||
|
||||
state = State("light.kitchen", "on")
|
||||
|
||||
assert not mock_conf.should_expose(state)
|
||||
entity_conf["should_expose"] = True
|
||||
assert mock_conf.should_expose(state)
|
||||
|
||||
entity_conf["should_expose"] = None
|
||||
assert mock_conf.should_expose(state)
|
||||
|
||||
await cloud_prefs.async_update(google_default_expose=["sensor"],)
|
||||
assert not mock_conf.should_expose(state)
|
||||
|
|
|
@ -355,6 +355,8 @@ async def test_websocket_status(
|
|||
"google_enabled": True,
|
||||
"google_entity_configs": {},
|
||||
"google_secure_devices_pin": None,
|
||||
"google_default_expose": None,
|
||||
"alexa_default_expose": None,
|
||||
"alexa_entity_configs": {},
|
||||
"alexa_report_state": False,
|
||||
"google_report_state": False,
|
||||
|
@ -487,6 +489,8 @@ async def test_websocket_update_preferences(
|
|||
"alexa_enabled": False,
|
||||
"google_enabled": False,
|
||||
"google_secure_devices_pin": "1234",
|
||||
"google_default_expose": ["light", "switch"],
|
||||
"alexa_default_expose": ["sensor", "media_player"],
|
||||
}
|
||||
)
|
||||
response = await client.receive_json()
|
||||
|
@ -495,6 +499,8 @@ async def test_websocket_update_preferences(
|
|||
assert not setup_api.google_enabled
|
||||
assert not setup_api.alexa_enabled
|
||||
assert setup_api.google_secure_devices_pin == "1234"
|
||||
assert setup_api.google_default_expose == ["light", "switch"]
|
||||
assert setup_api.alexa_default_expose == ["sensor", "media_player"]
|
||||
|
||||
|
||||
async def test_websocket_update_preferences_require_relink(
|
||||
|
@ -746,6 +752,25 @@ async def test_update_google_entity(hass, hass_ws_client, setup_api, mock_cloud_
|
|||
"disable_2fa": False,
|
||||
}
|
||||
|
||||
await client.send_json(
|
||||
{
|
||||
"id": 6,
|
||||
"type": "cloud/google_assistant/entities/update",
|
||||
"entity_id": "light.kitchen",
|
||||
"should_expose": None,
|
||||
}
|
||||
)
|
||||
response = await client.receive_json()
|
||||
|
||||
assert response["success"]
|
||||
prefs = hass.data[DOMAIN].client.prefs
|
||||
assert prefs.google_entity_configs["light.kitchen"] == {
|
||||
"should_expose": None,
|
||||
"override_name": "updated name",
|
||||
"aliases": ["lefty", "righty"],
|
||||
"disable_2fa": False,
|
||||
}
|
||||
|
||||
|
||||
async def test_enabling_remote_trusted_proxies_local4(
|
||||
hass, hass_ws_client, setup_api, mock_cloud_login
|
||||
|
@ -834,6 +859,20 @@ async def test_update_alexa_entity(hass, hass_ws_client, setup_api, mock_cloud_l
|
|||
prefs = hass.data[DOMAIN].client.prefs
|
||||
assert prefs.alexa_entity_configs["light.kitchen"] == {"should_expose": False}
|
||||
|
||||
await client.send_json(
|
||||
{
|
||||
"id": 6,
|
||||
"type": "cloud/alexa/entities/update",
|
||||
"entity_id": "light.kitchen",
|
||||
"should_expose": None,
|
||||
}
|
||||
)
|
||||
response = await client.receive_json()
|
||||
|
||||
assert response["success"]
|
||||
prefs = hass.data[DOMAIN].client.prefs
|
||||
assert prefs.alexa_entity_configs["light.kitchen"] == {"should_expose": None}
|
||||
|
||||
|
||||
async def test_sync_alexa_entities_timeout(
|
||||
hass, hass_ws_client, setup_api, mock_cloud_login
|
||||
|
|
Loading…
Reference in New Issue