Google assistant sync (#13392)

* Add Google Assistant Sync API

* Update const.py

* Async/await
This commit is contained in:
Paulus Schoutsen 2018-03-23 12:13:52 -07:00 committed by GitHub
parent 2532d67b9a
commit 4bd6776443
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 71 additions and 26 deletions

View file

@ -16,9 +16,9 @@ from .const import DOMAIN, REQUEST_TIMEOUT
_LOGGER = logging.getLogger(__name__)
@asyncio.coroutine
def async_setup(hass):
async def async_setup(hass):
"""Initialize the HTTP API."""
hass.http.register_view(GoogleActionsSyncView)
hass.http.register_view(CloudLoginView)
hass.http.register_view(CloudLogoutView)
hass.http.register_view(CloudAccountView)
@ -38,12 +38,11 @@ _CLOUD_ERRORS = {
def _handle_cloud_errors(handler):
"""Handle auth errors."""
@asyncio.coroutine
@wraps(handler)
def error_handler(view, request, *args, **kwargs):
async def error_handler(view, request, *args, **kwargs):
"""Handle exceptions that raise from the wrapped request handler."""
try:
result = yield from handler(view, request, *args, **kwargs)
result = await handler(view, request, *args, **kwargs)
return result
except (auth_api.CloudError, asyncio.TimeoutError) as err:
@ -57,6 +56,31 @@ def _handle_cloud_errors(handler):
return error_handler
class GoogleActionsSyncView(HomeAssistantView):
"""Trigger a Google Actions Smart Home Sync."""
url = '/api/cloud/google_actions/sync'
name = 'api:cloud:google_actions/sync'
@_handle_cloud_errors
async def post(self, request):
"""Trigger a Google Actions sync."""
hass = request.app['hass']
cloud = hass.data[DOMAIN]
websession = hass.helpers.aiohttp_client.async_get_clientsession()
with async_timeout.timeout(REQUEST_TIMEOUT, loop=hass.loop):
await hass.async_add_job(auth_api.check_token, cloud)
with async_timeout.timeout(REQUEST_TIMEOUT, loop=hass.loop):
req = await websession.post(
cloud.google_actions_sync_url, headers={
'authorization': cloud.id_token
})
return self.json({}, status_code=req.status)
class CloudLoginView(HomeAssistantView):
"""Login to Home Assistant cloud."""
@ -68,19 +92,18 @@ class CloudLoginView(HomeAssistantView):
vol.Required('email'): str,
vol.Required('password'): str,
}))
@asyncio.coroutine
def post(self, request, data):
async def post(self, request, data):
"""Handle login request."""
hass = request.app['hass']
cloud = hass.data[DOMAIN]
with async_timeout.timeout(REQUEST_TIMEOUT, loop=hass.loop):
yield from hass.async_add_job(auth_api.login, cloud, data['email'],
data['password'])
await hass.async_add_job(auth_api.login, cloud, data['email'],
data['password'])
hass.async_add_job(cloud.iot.connect)
# Allow cloud to start connecting.
yield from asyncio.sleep(0, loop=hass.loop)
await asyncio.sleep(0, loop=hass.loop)
return self.json(_account_data(cloud))
@ -91,14 +114,13 @@ class CloudLogoutView(HomeAssistantView):
name = 'api:cloud:logout'
@_handle_cloud_errors
@asyncio.coroutine
def post(self, request):
async def post(self, request):
"""Handle logout request."""
hass = request.app['hass']
cloud = hass.data[DOMAIN]
with async_timeout.timeout(REQUEST_TIMEOUT, loop=hass.loop):
yield from cloud.logout()
await cloud.logout()
return self.json_message('ok')
@ -109,8 +131,7 @@ class CloudAccountView(HomeAssistantView):
url = '/api/cloud/account'
name = 'api:cloud:account'
@asyncio.coroutine
def get(self, request):
async def get(self, request):
"""Get account info."""
hass = request.app['hass']
cloud = hass.data[DOMAIN]
@ -132,14 +153,13 @@ class CloudRegisterView(HomeAssistantView):
vol.Required('email'): str,
vol.Required('password'): vol.All(str, vol.Length(min=6)),
}))
@asyncio.coroutine
def post(self, request, data):
async def post(self, request, data):
"""Handle registration request."""
hass = request.app['hass']
cloud = hass.data[DOMAIN]
with async_timeout.timeout(REQUEST_TIMEOUT, loop=hass.loop):
yield from hass.async_add_job(
await hass.async_add_job(
auth_api.register, cloud, data['email'], data['password'])
return self.json_message('ok')
@ -155,14 +175,13 @@ class CloudResendConfirmView(HomeAssistantView):
@RequestDataValidator(vol.Schema({
vol.Required('email'): str,
}))
@asyncio.coroutine
def post(self, request, data):
async def post(self, request, data):
"""Handle resending confirm email code request."""
hass = request.app['hass']
cloud = hass.data[DOMAIN]
with async_timeout.timeout(REQUEST_TIMEOUT, loop=hass.loop):
yield from hass.async_add_job(
await hass.async_add_job(
auth_api.resend_email_confirm, cloud, data['email'])
return self.json_message('ok')
@ -178,14 +197,13 @@ class CloudForgotPasswordView(HomeAssistantView):
@RequestDataValidator(vol.Schema({
vol.Required('email'): str,
}))
@asyncio.coroutine
def post(self, request, data):
async def post(self, request, data):
"""Handle forgot password request."""
hass = request.app['hass']
cloud = hass.data[DOMAIN]
with async_timeout.timeout(REQUEST_TIMEOUT, loop=hass.loop):
yield from hass.async_add_job(
await hass.async_add_job(
auth_api.forgot_password, cloud, data['email'])
return self.json_message('ok')