Cloud conf (#18216)
* Add original config to entityfilter * Add alexa/google config to cloud status call * Lint
This commit is contained in:
parent
8de79ed57c
commit
bf54582d76
5 changed files with 74 additions and 20 deletions
|
@ -122,7 +122,7 @@ class Cloud:
|
||||||
self.hass = hass
|
self.hass = hass
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
self.alexa_config = alexa
|
self.alexa_config = alexa
|
||||||
self._google_actions = google_actions
|
self.google_actions_user_conf = google_actions
|
||||||
self._gactions_config = None
|
self._gactions_config = None
|
||||||
self._prefs = None
|
self._prefs = None
|
||||||
self.id_token = None
|
self.id_token = None
|
||||||
|
@ -180,7 +180,7 @@ class Cloud:
|
||||||
def gactions_config(self):
|
def gactions_config(self):
|
||||||
"""Return the Google Assistant config."""
|
"""Return the Google Assistant config."""
|
||||||
if self._gactions_config is None:
|
if self._gactions_config is None:
|
||||||
conf = self._google_actions
|
conf = self.google_actions_user_conf
|
||||||
|
|
||||||
def should_expose(entity):
|
def should_expose(entity):
|
||||||
"""If an entity should be exposed."""
|
"""If an entity should be exposed."""
|
||||||
|
|
|
@ -11,6 +11,8 @@ from homeassistant.components.http import HomeAssistantView
|
||||||
from homeassistant.components.http.data_validator import (
|
from homeassistant.components.http.data_validator import (
|
||||||
RequestDataValidator)
|
RequestDataValidator)
|
||||||
from homeassistant.components import websocket_api
|
from homeassistant.components import websocket_api
|
||||||
|
from homeassistant.components.alexa import smart_home as alexa_sh
|
||||||
|
from homeassistant.components.google_assistant import smart_home as google_sh
|
||||||
|
|
||||||
from . import auth_api
|
from . import auth_api
|
||||||
from .const import DOMAIN, REQUEST_TIMEOUT
|
from .const import DOMAIN, REQUEST_TIMEOUT
|
||||||
|
@ -307,5 +309,9 @@ def _account_data(cloud):
|
||||||
'email': claims['email'],
|
'email': claims['email'],
|
||||||
'cloud': cloud.iot.state,
|
'cloud': cloud.iot.state,
|
||||||
'google_enabled': cloud.google_enabled,
|
'google_enabled': cloud.google_enabled,
|
||||||
|
'google_entities': cloud.google_actions_user_conf['filter'].config,
|
||||||
|
'google_domains': list(google_sh.DOMAIN_TO_GOOGLE_TYPES),
|
||||||
'alexa_enabled': cloud.alexa_enabled,
|
'alexa_enabled': cloud.alexa_enabled,
|
||||||
|
'alexa_entities': cloud.alexa_config.should_expose.config,
|
||||||
|
'alexa_domains': list(alexa_sh.ENTITY_ADAPTERS),
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,18 @@ CONF_INCLUDE_ENTITIES = 'include_entities'
|
||||||
CONF_EXCLUDE_DOMAINS = 'exclude_domains'
|
CONF_EXCLUDE_DOMAINS = 'exclude_domains'
|
||||||
CONF_EXCLUDE_ENTITIES = 'exclude_entities'
|
CONF_EXCLUDE_ENTITIES = 'exclude_entities'
|
||||||
|
|
||||||
|
|
||||||
|
def _convert_filter(config):
|
||||||
|
filt = generate_filter(
|
||||||
|
config[CONF_INCLUDE_DOMAINS],
|
||||||
|
config[CONF_INCLUDE_ENTITIES],
|
||||||
|
config[CONF_EXCLUDE_DOMAINS],
|
||||||
|
config[CONF_EXCLUDE_ENTITIES],
|
||||||
|
)
|
||||||
|
filt.config = config
|
||||||
|
return filt
|
||||||
|
|
||||||
|
|
||||||
FILTER_SCHEMA = vol.All(
|
FILTER_SCHEMA = vol.All(
|
||||||
vol.Schema({
|
vol.Schema({
|
||||||
vol.Optional(CONF_EXCLUDE_DOMAINS, default=[]):
|
vol.Optional(CONF_EXCLUDE_DOMAINS, default=[]):
|
||||||
|
@ -18,13 +30,7 @@ FILTER_SCHEMA = vol.All(
|
||||||
vol.Optional(CONF_INCLUDE_DOMAINS, default=[]):
|
vol.Optional(CONF_INCLUDE_DOMAINS, default=[]):
|
||||||
vol.All(cv.ensure_list, [cv.string]),
|
vol.All(cv.ensure_list, [cv.string]),
|
||||||
vol.Optional(CONF_INCLUDE_ENTITIES, default=[]): cv.entity_ids,
|
vol.Optional(CONF_INCLUDE_ENTITIES, default=[]): cv.entity_ids,
|
||||||
}),
|
}), _convert_filter)
|
||||||
lambda config: generate_filter(
|
|
||||||
config[CONF_INCLUDE_DOMAINS],
|
|
||||||
config[CONF_INCLUDE_ENTITIES],
|
|
||||||
config[CONF_EXCLUDE_DOMAINS],
|
|
||||||
config[CONF_EXCLUDE_ENTITIES],
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
def generate_filter(include_domains, include_entities,
|
def generate_filter(include_domains, include_entities,
|
||||||
|
@ -64,8 +70,8 @@ def generate_filter(include_domains, include_entities,
|
||||||
|
|
||||||
# Case 4 - both includes and excludes specified
|
# Case 4 - both includes and excludes specified
|
||||||
# Case 4a - include domain specified
|
# Case 4a - include domain specified
|
||||||
# - if domain is included, and entity not excluded, pass
|
# - if domain is included, pass if entity not excluded
|
||||||
# - if domain is not included, and entity not included, fail
|
# - if domain is not included, pass if entity is included
|
||||||
# note: if both include and exclude domains specified,
|
# note: if both include and exclude domains specified,
|
||||||
# the exclude domains are ignored
|
# the exclude domains are ignored
|
||||||
if include_d:
|
if include_d:
|
||||||
|
@ -79,8 +85,8 @@ def generate_filter(include_domains, include_entities,
|
||||||
return entity_filter_4a
|
return entity_filter_4a
|
||||||
|
|
||||||
# Case 4b - exclude domain specified
|
# Case 4b - exclude domain specified
|
||||||
# - if domain is excluded, and entity not included, fail
|
# - if domain is excluded, pass if entity is included
|
||||||
# - if domain is not excluded, and entity not excluded, pass
|
# - if domain is not excluded, pass if entity not excluded
|
||||||
if exclude_d:
|
if exclude_d:
|
||||||
def entity_filter_4b(entity_id):
|
def entity_filter_4b(entity_id):
|
||||||
"""Return filter function for case 4b."""
|
"""Return filter function for case 4b."""
|
||||||
|
|
|
@ -35,6 +35,16 @@ def setup_api(hass):
|
||||||
'relayer': 'relayer',
|
'relayer': 'relayer',
|
||||||
'google_actions_sync_url': GOOGLE_ACTIONS_SYNC_URL,
|
'google_actions_sync_url': GOOGLE_ACTIONS_SYNC_URL,
|
||||||
'subscription_info_url': SUBSCRIPTION_INFO_URL,
|
'subscription_info_url': SUBSCRIPTION_INFO_URL,
|
||||||
|
'google_actions': {
|
||||||
|
'filter': {
|
||||||
|
'include_domains': 'light'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'alexa': {
|
||||||
|
'filter': {
|
||||||
|
'include_entities': ['light.kitchen', 'switch.ac']
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
return mock_cloud_prefs(hass)
|
return mock_cloud_prefs(hass)
|
||||||
|
|
||||||
|
@ -325,17 +335,37 @@ async def test_websocket_status(hass, hass_ws_client, mock_cloud_fixture):
|
||||||
}, 'test')
|
}, 'test')
|
||||||
hass.data[DOMAIN].iot.state = iot.STATE_CONNECTED
|
hass.data[DOMAIN].iot.state = iot.STATE_CONNECTED
|
||||||
client = await hass_ws_client(hass)
|
client = await hass_ws_client(hass)
|
||||||
await client.send_json({
|
|
||||||
'id': 5,
|
with patch.dict(
|
||||||
'type': 'cloud/status'
|
'homeassistant.components.google_assistant.smart_home.'
|
||||||
})
|
'DOMAIN_TO_GOOGLE_TYPES', {'light': None}, clear=True
|
||||||
response = await client.receive_json()
|
), patch.dict('homeassistant.components.alexa.smart_home.ENTITY_ADAPTERS',
|
||||||
|
{'switch': None}, clear=True):
|
||||||
|
await client.send_json({
|
||||||
|
'id': 5,
|
||||||
|
'type': 'cloud/status'
|
||||||
|
})
|
||||||
|
response = await client.receive_json()
|
||||||
assert response['result'] == {
|
assert response['result'] == {
|
||||||
'logged_in': True,
|
'logged_in': True,
|
||||||
'email': 'hello@home-assistant.io',
|
'email': 'hello@home-assistant.io',
|
||||||
'cloud': 'connected',
|
'cloud': 'connected',
|
||||||
'alexa_enabled': True,
|
'alexa_enabled': True,
|
||||||
|
'alexa_entities': {
|
||||||
|
'include_domains': [],
|
||||||
|
'include_entities': ['light.kitchen', 'switch.ac'],
|
||||||
|
'exclude_domains': [],
|
||||||
|
'exclude_entities': [],
|
||||||
|
},
|
||||||
|
'alexa_domains': ['switch'],
|
||||||
'google_enabled': True,
|
'google_enabled': True,
|
||||||
|
'google_entities': {
|
||||||
|
'include_domains': ['light'],
|
||||||
|
'include_entities': [],
|
||||||
|
'exclude_domains': [],
|
||||||
|
'exclude_entities': [],
|
||||||
|
},
|
||||||
|
'google_domains': ['light'],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
"""The tests for the EntityFilter component."""
|
"""The tests for the EntityFilter component."""
|
||||||
from homeassistant.helpers.entityfilter import generate_filter
|
from homeassistant.helpers.entityfilter import generate_filter, FILTER_SCHEMA
|
||||||
|
|
||||||
|
|
||||||
def test_no_filters_case_1():
|
def test_no_filters_case_1():
|
||||||
|
@ -78,7 +78,7 @@ def test_exclude_domain_case4b():
|
||||||
assert testfilter("sun.sun") is True
|
assert testfilter("sun.sun") is True
|
||||||
|
|
||||||
|
|
||||||
def testno_domain_case4c():
|
def test_no_domain_case4c():
|
||||||
"""Test case 4c - include and exclude specified, with no domains."""
|
"""Test case 4c - include and exclude specified, with no domains."""
|
||||||
incl_dom = {}
|
incl_dom = {}
|
||||||
incl_ent = {'binary_sensor.working'}
|
incl_ent = {'binary_sensor.working'}
|
||||||
|
@ -93,3 +93,15 @@ def testno_domain_case4c():
|
||||||
assert testfilter("binary_sensor.working")
|
assert testfilter("binary_sensor.working")
|
||||||
assert testfilter("binary_sensor.another") is False
|
assert testfilter("binary_sensor.another") is False
|
||||||
assert testfilter("sun.sun") is False
|
assert testfilter("sun.sun") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_filter_schema():
|
||||||
|
"""Test filter schema."""
|
||||||
|
conf = {
|
||||||
|
'include_domains': ['light'],
|
||||||
|
'include_entities': ['switch.kitchen'],
|
||||||
|
'exclude_domains': ['cover'],
|
||||||
|
'exclude_entities': ['light.kitchen']
|
||||||
|
}
|
||||||
|
filt = FILTER_SCHEMA(conf)
|
||||||
|
assert filt.config == conf
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue