Cloud to set up Alexa conditionally (#49136)

This commit is contained in:
Paulus Schoutsen 2021-04-13 09:31:41 -07:00 committed by GitHub
parent 28347e19c5
commit ba93a033a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 10 deletions

View File

@ -9,6 +9,7 @@ import async_timeout
from hass_nabucasa import Cloud, cloud_api from hass_nabucasa import Cloud, cloud_api
from homeassistant.components.alexa import ( from homeassistant.components.alexa import (
DOMAIN as ALEXA_DOMAIN,
config as alexa_config, config as alexa_config,
entities as alexa_entities, entities as alexa_entities,
errors as alexa_errors, errors as alexa_errors,
@ -18,6 +19,7 @@ from homeassistant.const import CLOUD_NEVER_EXPOSED_ENTITIES, HTTP_BAD_REQUEST
from homeassistant.core import HomeAssistant, callback, split_entity_id from homeassistant.core import HomeAssistant, callback, split_entity_id
from homeassistant.helpers import entity_registry from homeassistant.helpers import entity_registry
from homeassistant.helpers.event import async_call_later from homeassistant.helpers.event import async_call_later
from homeassistant.setup import async_setup_component
from homeassistant.util.dt import utcnow from homeassistant.util.dt import utcnow
from .const import CONF_ENTITY_CONFIG, CONF_FILTER, PREF_SHOULD_EXPOSE, RequireRelink from .const import CONF_ENTITY_CONFIG, CONF_FILTER, PREF_SHOULD_EXPOSE, RequireRelink
@ -103,6 +105,11 @@ class AlexaConfig(alexa_config.AbstractConfig):
"""Return an identifier for the user that represents this config.""" """Return an identifier for the user that represents this config."""
return self._cloud_user return self._cloud_user
async def async_initialize(self):
"""Initialize the Alexa config."""
if self.enabled and ALEXA_DOMAIN not in self.hass.config.components:
await async_setup_component(self.hass, ALEXA_DOMAIN, {})
def should_expose(self, entity_id): def should_expose(self, entity_id):
"""If an entity should be exposed.""" """If an entity should be exposed."""
if entity_id in CLOUD_NEVER_EXPOSED_ENTITIES: if entity_id in CLOUD_NEVER_EXPOSED_ENTITIES:
@ -160,6 +167,9 @@ class AlexaConfig(alexa_config.AbstractConfig):
async def _async_prefs_updated(self, prefs): async def _async_prefs_updated(self, prefs):
"""Handle updated preferences.""" """Handle updated preferences."""
if ALEXA_DOMAIN not in self.hass.config.components and self.enabled:
await async_setup_component(self.hass, ALEXA_DOMAIN, {})
if self.should_report_state != self.is_reporting_states: if self.should_report_state != self.is_reporting_states:
if self.should_report_state: if self.should_report_state:
await self.async_enable_proactive_mode() await self.async_enable_proactive_mode()

View File

@ -90,6 +90,7 @@ class CloudClient(Interface):
self._alexa_config = alexa_config.AlexaConfig( self._alexa_config = alexa_config.AlexaConfig(
self._hass, self.alexa_user_config, cloud_user, self._prefs, self.cloud self._hass, self.alexa_user_config, cloud_user, self._prefs, self.cloud
) )
await self._alexa_config.async_initialize()
return self._alexa_config return self._alexa_config

View File

@ -3,7 +3,7 @@
"name": "Home Assistant Cloud", "name": "Home Assistant Cloud",
"documentation": "https://www.home-assistant.io/integrations/cloud", "documentation": "https://www.home-assistant.io/integrations/cloud",
"requirements": ["hass-nabucasa==0.43.0"], "requirements": ["hass-nabucasa==0.43.0"],
"dependencies": ["http", "webhook", "alexa"], "dependencies": ["http", "webhook"],
"after_dependencies": ["google_assistant"], "after_dependencies": ["google_assistant", "alexa"],
"codeowners": ["@home-assistant/cloud"] "codeowners": ["@home-assistant/cloud"]
} }

View File

@ -2,6 +2,8 @@
import contextlib import contextlib
from unittest.mock import AsyncMock, Mock, patch from unittest.mock import AsyncMock, Mock, patch
import pytest
from homeassistant.components.cloud import ALEXA_SCHEMA, alexa_config from homeassistant.components.cloud import ALEXA_SCHEMA, alexa_config
from homeassistant.helpers.entity_registry import EVENT_ENTITY_REGISTRY_UPDATED from homeassistant.helpers.entity_registry import EVENT_ENTITY_REGISTRY_UPDATED
from homeassistant.util.dt import utcnow from homeassistant.util.dt import utcnow
@ -9,15 +11,22 @@ from homeassistant.util.dt import utcnow
from tests.common import async_fire_time_changed from tests.common import async_fire_time_changed
async def test_alexa_config_expose_entity_prefs(hass, cloud_prefs): @pytest.fixture()
def cloud_stub():
"""Stub the cloud."""
return Mock(is_logged_in=True, subscription_expired=False)
async def test_alexa_config_expose_entity_prefs(hass, cloud_prefs, cloud_stub):
"""Test Alexa config should expose using prefs.""" """Test Alexa config should expose using prefs."""
entity_conf = {"should_expose": False} entity_conf = {"should_expose": False}
await cloud_prefs.async_update( await cloud_prefs.async_update(
alexa_entity_configs={"light.kitchen": entity_conf}, alexa_entity_configs={"light.kitchen": entity_conf},
alexa_default_expose=["light"], alexa_default_expose=["light"],
alexa_enabled=True,
) )
conf = alexa_config.AlexaConfig( conf = alexa_config.AlexaConfig(
hass, ALEXA_SCHEMA({}), "mock-user-id", cloud_prefs, None hass, ALEXA_SCHEMA({}), "mock-user-id", cloud_prefs, cloud_stub
) )
assert not conf.should_expose("light.kitchen") assert not conf.should_expose("light.kitchen")
@ -27,16 +36,19 @@ async def test_alexa_config_expose_entity_prefs(hass, cloud_prefs):
entity_conf["should_expose"] = None entity_conf["should_expose"] = None
assert conf.should_expose("light.kitchen") assert conf.should_expose("light.kitchen")
assert "alexa" not in hass.config.components
await cloud_prefs.async_update( await cloud_prefs.async_update(
alexa_default_expose=["sensor"], alexa_default_expose=["sensor"],
) )
await hass.async_block_till_done()
assert "alexa" in hass.config.components
assert not conf.should_expose("light.kitchen") assert not conf.should_expose("light.kitchen")
async def test_alexa_config_report_state(hass, cloud_prefs): async def test_alexa_config_report_state(hass, cloud_prefs, cloud_stub):
"""Test Alexa config should expose using prefs.""" """Test Alexa config should expose using prefs."""
conf = alexa_config.AlexaConfig( conf = alexa_config.AlexaConfig(
hass, ALEXA_SCHEMA({}), "mock-user-id", cloud_prefs, None hass, ALEXA_SCHEMA({}), "mock-user-id", cloud_prefs, cloud_stub
) )
assert cloud_prefs.alexa_report_state is False assert cloud_prefs.alexa_report_state is False
@ -117,9 +129,11 @@ def patch_sync_helper():
yield to_update, to_remove yield to_update, to_remove
async def test_alexa_update_expose_trigger_sync(hass, cloud_prefs): async def test_alexa_update_expose_trigger_sync(hass, cloud_prefs, cloud_stub):
"""Test Alexa config responds to updating exposed entities.""" """Test Alexa config responds to updating exposed entities."""
alexa_config.AlexaConfig(hass, ALEXA_SCHEMA({}), "mock-user-id", cloud_prefs, None) alexa_config.AlexaConfig(
hass, ALEXA_SCHEMA({}), "mock-user-id", cloud_prefs, cloud_stub
)
with patch_sync_helper() as (to_update, to_remove): with patch_sync_helper() as (to_update, to_remove):
await cloud_prefs.async_update_alexa_entity_config( await cloud_prefs.async_update_alexa_entity_config(
@ -202,9 +216,11 @@ async def test_alexa_entity_registry_sync(hass, mock_cloud_login, cloud_prefs):
assert to_remove == [] assert to_remove == []
async def test_alexa_update_report_state(hass, cloud_prefs): async def test_alexa_update_report_state(hass, cloud_prefs, cloud_stub):
"""Test Alexa config responds to reporting state.""" """Test Alexa config responds to reporting state."""
alexa_config.AlexaConfig(hass, ALEXA_SCHEMA({}), "mock-user-id", cloud_prefs, None) alexa_config.AlexaConfig(
hass, ALEXA_SCHEMA({}), "mock-user-id", cloud_prefs, cloud_stub
)
with patch( with patch(
"homeassistant.components.cloud.alexa_config.AlexaConfig.async_sync_entities", "homeassistant.components.cloud.alexa_config.AlexaConfig.async_sync_entities",