Add TT WS API (#28599)
* Add TT WS API * Add a test * Correctly convert TT errrors
This commit is contained in:
parent
b2071b81c1
commit
bd54ff3c02
7 changed files with 93 additions and 20 deletions
|
@ -6,7 +6,7 @@ import logging
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import async_timeout
|
import async_timeout
|
||||||
import attr
|
import attr
|
||||||
from hass_nabucasa import Cloud, auth
|
from hass_nabucasa import Cloud, auth, thingtalk
|
||||||
from hass_nabucasa.const import STATE_DISCONNECTED
|
from hass_nabucasa.const import STATE_DISCONNECTED
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
@ -75,28 +75,29 @@ _CLOUD_ERRORS = {
|
||||||
|
|
||||||
async def async_setup(hass):
|
async def async_setup(hass):
|
||||||
"""Initialize the HTTP API."""
|
"""Initialize the HTTP API."""
|
||||||
hass.components.websocket_api.async_register_command(
|
async_register_command = hass.components.websocket_api.async_register_command
|
||||||
WS_TYPE_STATUS, websocket_cloud_status, SCHEMA_WS_STATUS
|
async_register_command(WS_TYPE_STATUS, websocket_cloud_status, SCHEMA_WS_STATUS)
|
||||||
)
|
async_register_command(
|
||||||
hass.components.websocket_api.async_register_command(
|
|
||||||
WS_TYPE_SUBSCRIPTION, websocket_subscription, SCHEMA_WS_SUBSCRIPTION
|
WS_TYPE_SUBSCRIPTION, websocket_subscription, SCHEMA_WS_SUBSCRIPTION
|
||||||
)
|
)
|
||||||
hass.components.websocket_api.async_register_command(websocket_update_prefs)
|
async_register_command(websocket_update_prefs)
|
||||||
hass.components.websocket_api.async_register_command(
|
async_register_command(
|
||||||
WS_TYPE_HOOK_CREATE, websocket_hook_create, SCHEMA_WS_HOOK_CREATE
|
WS_TYPE_HOOK_CREATE, websocket_hook_create, SCHEMA_WS_HOOK_CREATE
|
||||||
)
|
)
|
||||||
hass.components.websocket_api.async_register_command(
|
async_register_command(
|
||||||
WS_TYPE_HOOK_DELETE, websocket_hook_delete, SCHEMA_WS_HOOK_DELETE
|
WS_TYPE_HOOK_DELETE, websocket_hook_delete, SCHEMA_WS_HOOK_DELETE
|
||||||
)
|
)
|
||||||
hass.components.websocket_api.async_register_command(websocket_remote_connect)
|
async_register_command(websocket_remote_connect)
|
||||||
hass.components.websocket_api.async_register_command(websocket_remote_disconnect)
|
async_register_command(websocket_remote_disconnect)
|
||||||
|
|
||||||
hass.components.websocket_api.async_register_command(google_assistant_list)
|
async_register_command(google_assistant_list)
|
||||||
hass.components.websocket_api.async_register_command(google_assistant_update)
|
async_register_command(google_assistant_update)
|
||||||
|
|
||||||
hass.components.websocket_api.async_register_command(alexa_list)
|
async_register_command(alexa_list)
|
||||||
hass.components.websocket_api.async_register_command(alexa_update)
|
async_register_command(alexa_update)
|
||||||
hass.components.websocket_api.async_register_command(alexa_sync)
|
async_register_command(alexa_sync)
|
||||||
|
|
||||||
|
async_register_command(thingtalk_convert)
|
||||||
|
|
||||||
hass.http.register_view(GoogleActionsSyncView)
|
hass.http.register_view(GoogleActionsSyncView)
|
||||||
hass.http.register_view(CloudLoginView)
|
hass.http.register_view(CloudLoginView)
|
||||||
|
@ -592,3 +593,18 @@ async def alexa_sync(hass, connection, msg):
|
||||||
connection.send_result(msg["id"])
|
connection.send_result(msg["id"])
|
||||||
else:
|
else:
|
||||||
connection.send_error(msg["id"], ws_const.ERR_UNKNOWN_ERROR, "Unknown error")
|
connection.send_error(msg["id"], ws_const.ERR_UNKNOWN_ERROR, "Unknown error")
|
||||||
|
|
||||||
|
|
||||||
|
@websocket_api.async_response
|
||||||
|
@websocket_api.websocket_command({"type": "cloud/thingtalk/convert", "query": str})
|
||||||
|
async def thingtalk_convert(hass, connection, msg):
|
||||||
|
"""Convert a query."""
|
||||||
|
cloud = hass.data[DOMAIN]
|
||||||
|
|
||||||
|
with async_timeout.timeout(10):
|
||||||
|
try:
|
||||||
|
connection.send_result(
|
||||||
|
msg["id"], await thingtalk.async_convert(cloud, msg["query"])
|
||||||
|
)
|
||||||
|
except thingtalk.ThingTalkConversionError as err:
|
||||||
|
connection.send_error(msg["id"], ws_const.ERR_UNKNOWN_ERROR, str(err))
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"domain": "cloud",
|
"domain": "cloud",
|
||||||
"name": "Cloud",
|
"name": "Cloud",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/cloud",
|
"documentation": "https://www.home-assistant.io/integrations/cloud",
|
||||||
"requirements": ["hass-nabucasa==0.26"],
|
"requirements": ["hass-nabucasa==0.29"],
|
||||||
"dependencies": ["http", "webhook"],
|
"dependencies": ["http", "webhook"],
|
||||||
"codeowners": ["@home-assistant/cloud"]
|
"codeowners": ["@home-assistant/cloud"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,6 +108,8 @@ class ActiveConnection:
|
||||||
@callback
|
@callback
|
||||||
def async_handle_exception(self, msg, err):
|
def async_handle_exception(self, msg, err):
|
||||||
"""Handle an exception while processing a handler."""
|
"""Handle an exception while processing a handler."""
|
||||||
|
log_handler = self.logger.error
|
||||||
|
|
||||||
if isinstance(err, Unauthorized):
|
if isinstance(err, Unauthorized):
|
||||||
code = const.ERR_UNAUTHORIZED
|
code = const.ERR_UNAUTHORIZED
|
||||||
err_message = "Unauthorized"
|
err_message = "Unauthorized"
|
||||||
|
@ -120,6 +122,8 @@ class ActiveConnection:
|
||||||
else:
|
else:
|
||||||
code = const.ERR_UNKNOWN_ERROR
|
code = const.ERR_UNKNOWN_ERROR
|
||||||
err_message = "Unknown error"
|
err_message = "Unknown error"
|
||||||
|
log_handler = self.logger.exception
|
||||||
|
|
||||||
|
log_handler("Error handling message: %s", err_message)
|
||||||
|
|
||||||
self.logger.exception("Error handling message: %s", err_message)
|
|
||||||
self.send_message(messages.error_message(msg["id"], code, err_message))
|
self.send_message(messages.error_message(msg["id"], code, err_message))
|
||||||
|
|
|
@ -10,7 +10,7 @@ certifi>=2019.9.11
|
||||||
contextvars==2.4;python_version<"3.7"
|
contextvars==2.4;python_version<"3.7"
|
||||||
cryptography==2.8
|
cryptography==2.8
|
||||||
distro==1.4.0
|
distro==1.4.0
|
||||||
hass-nabucasa==0.26
|
hass-nabucasa==0.29
|
||||||
home-assistant-frontend==20191025.1
|
home-assistant-frontend==20191025.1
|
||||||
importlib-metadata==0.23
|
importlib-metadata==0.23
|
||||||
jinja2>=2.10.3
|
jinja2>=2.10.3
|
||||||
|
|
|
@ -625,7 +625,7 @@ habitipy==0.2.0
|
||||||
hangups==0.4.9
|
hangups==0.4.9
|
||||||
|
|
||||||
# homeassistant.components.cloud
|
# homeassistant.components.cloud
|
||||||
hass-nabucasa==0.26
|
hass-nabucasa==0.29
|
||||||
|
|
||||||
# homeassistant.components.mqtt
|
# homeassistant.components.mqtt
|
||||||
hbmqtt==0.9.5
|
hbmqtt==0.9.5
|
||||||
|
|
|
@ -204,7 +204,7 @@ ha-ffmpeg==2.0
|
||||||
hangups==0.4.9
|
hangups==0.4.9
|
||||||
|
|
||||||
# homeassistant.components.cloud
|
# homeassistant.components.cloud
|
||||||
hass-nabucasa==0.26
|
hass-nabucasa==0.29
|
||||||
|
|
||||||
# homeassistant.components.mqtt
|
# homeassistant.components.mqtt
|
||||||
hbmqtt==0.9.5
|
hbmqtt==0.9.5
|
||||||
|
|
|
@ -7,6 +7,7 @@ import pytest
|
||||||
from jose import jwt
|
from jose import jwt
|
||||||
from hass_nabucasa.auth import Unauthenticated, UnknownError
|
from hass_nabucasa.auth import Unauthenticated, UnknownError
|
||||||
from hass_nabucasa.const import STATE_CONNECTED
|
from hass_nabucasa.const import STATE_CONNECTED
|
||||||
|
from hass_nabucasa import thingtalk
|
||||||
|
|
||||||
from homeassistant.core import State
|
from homeassistant.core import State
|
||||||
from homeassistant.auth.providers import trusted_networks as tn_auth
|
from homeassistant.auth.providers import trusted_networks as tn_auth
|
||||||
|
@ -871,3 +872,55 @@ async def test_enable_alexa_state_report_fail(
|
||||||
|
|
||||||
assert not response["success"]
|
assert not response["success"]
|
||||||
assert response["error"]["code"] == "alexa_relink"
|
assert response["error"]["code"] == "alexa_relink"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_thingtalk_convert(hass, hass_ws_client, setup_api):
|
||||||
|
"""Test that we can convert a query."""
|
||||||
|
client = await hass_ws_client(hass)
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.cloud.http_api.thingtalk.async_convert",
|
||||||
|
return_value=mock_coro({"hello": "world"}),
|
||||||
|
):
|
||||||
|
await client.send_json(
|
||||||
|
{"id": 5, "type": "cloud/thingtalk/convert", "query": "some-data"}
|
||||||
|
)
|
||||||
|
response = await client.receive_json()
|
||||||
|
|
||||||
|
assert response["success"]
|
||||||
|
assert response["result"] == {"hello": "world"}
|
||||||
|
|
||||||
|
|
||||||
|
async def test_thingtalk_convert_timeout(hass, hass_ws_client, setup_api):
|
||||||
|
"""Test that we can convert a query."""
|
||||||
|
client = await hass_ws_client(hass)
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.cloud.http_api.thingtalk.async_convert",
|
||||||
|
side_effect=asyncio.TimeoutError,
|
||||||
|
):
|
||||||
|
await client.send_json(
|
||||||
|
{"id": 5, "type": "cloud/thingtalk/convert", "query": "some-data"}
|
||||||
|
)
|
||||||
|
response = await client.receive_json()
|
||||||
|
|
||||||
|
assert not response["success"]
|
||||||
|
assert response["error"]["code"] == "timeout"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_thingtalk_convert_internal(hass, hass_ws_client, setup_api):
|
||||||
|
"""Test that we can convert a query."""
|
||||||
|
client = await hass_ws_client(hass)
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.cloud.http_api.thingtalk.async_convert",
|
||||||
|
side_effect=thingtalk.ThingTalkConversionError("Did not understand"),
|
||||||
|
):
|
||||||
|
await client.send_json(
|
||||||
|
{"id": 5, "type": "cloud/thingtalk/convert", "query": "some-data"}
|
||||||
|
)
|
||||||
|
response = await client.receive_json()
|
||||||
|
|
||||||
|
assert not response["success"]
|
||||||
|
assert response["error"]["code"] == "unknown_error"
|
||||||
|
assert response["error"]["message"] == "Did not understand"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue