"""Support for Google Actions Smart Home Control.""" import logging from aiohttp.web import Request, Response # Typing imports from homeassistant.components.http import HomeAssistantView from homeassistant.core import callback from homeassistant.const import CLOUD_NEVER_EXPOSED_ENTITIES from .const import ( GOOGLE_ASSISTANT_API_ENDPOINT, CONF_EXPOSE_BY_DEFAULT, CONF_EXPOSED_DOMAINS, CONF_ENTITY_CONFIG, CONF_EXPOSE, CONF_SECURE_DEVICES_PIN, ) from .smart_home import async_handle_message from .helpers import AbstractConfig _LOGGER = logging.getLogger(__name__) class GoogleConfig(AbstractConfig): """Config for manual setup of Google.""" def __init__(self, config): """Initialize the config.""" self._config = config @property def agent_user_id(self): """Return Agent User Id to use for query responses.""" return None @property def entity_config(self): """Return entity config.""" return self._config.get(CONF_ENTITY_CONFIG) or {} @property def secure_devices_pin(self): """Return entity config.""" return self._config.get(CONF_SECURE_DEVICES_PIN) def should_expose(self, state) -> bool: """Return if entity should be exposed.""" expose_by_default = self._config.get(CONF_EXPOSE_BY_DEFAULT) exposed_domains = self._config.get(CONF_EXPOSED_DOMAINS) if state.attributes.get("view") is not None: # Ignore entities that are views return False if state.entity_id in CLOUD_NEVER_EXPOSED_ENTITIES: return False explicit_expose = self.entity_config.get(state.entity_id, {}).get(CONF_EXPOSE) domain_exposed_by_default = ( expose_by_default and state.domain in exposed_domains ) # Expose an entity if the entity's domain is exposed by default and # the configuration doesn't explicitly exclude it from being # exposed, or if the entity is explicitly exposed is_default_exposed = domain_exposed_by_default and explicit_expose is not False return is_default_exposed or explicit_expose def should_2fa(self, state): """If an entity should have 2FA checked.""" return True @callback def async_register_http(hass, cfg): """Register HTTP views for Google Assistant.""" hass.http.register_view(GoogleAssistantView(GoogleConfig(cfg))) class GoogleAssistantView(HomeAssistantView): """Handle Google Assistant requests.""" url = GOOGLE_ASSISTANT_API_ENDPOINT name = "api:google_assistant" requires_auth = True def __init__(self, config): """Initialize the Google Assistant request handler.""" self.config = config async def post(self, request: Request) -> Response: """Handle Google Assistant requests.""" message = await request.json() # type: dict result = await async_handle_message( request.app["hass"], self.config, request["hass_user"].id, message ) return self.json(result)