1
mirror of https://github.com/home-assistant/core synced 2024-09-03 08:14:07 +02:00
ha-core/homeassistant/components/alexa/smart_home.py

79 lines
2.4 KiB
Python

"""Support for alexa Smart Home Skill API."""
import logging
import homeassistant.core as ha
from .const import API_DIRECTIVE, API_HEADER, EVENT_ALEXA_SMART_HOME
from .errors import AlexaBridgeUnreachableError, AlexaError
from .handlers import HANDLERS
from .messages import AlexaDirective
_LOGGER = logging.getLogger(__name__)
async def async_handle_message(hass, config, request, context=None, enabled=True):
"""Handle incoming API messages.
If enabled is False, the response to all messages will be a
BRIDGE_UNREACHABLE error. This can be used if the API has been disabled in
configuration.
"""
assert request[API_DIRECTIVE][API_HEADER]["payloadVersion"] == "3"
if context is None:
context = ha.Context()
directive = AlexaDirective(request)
try:
if not enabled:
raise AlexaBridgeUnreachableError(
"Alexa API not enabled in Home Assistant configuration"
)
await config.set_authorized(True)
if directive.has_endpoint:
directive.load_entity(hass, config)
funct_ref = HANDLERS.get((directive.namespace, directive.name))
if funct_ref:
response = await funct_ref(hass, config, directive, context)
if directive.has_endpoint:
response.merge_context_properties(directive.endpoint)
else:
_LOGGER.warning(
"Unsupported API request %s/%s", directive.namespace, directive.name
)
response = directive.error()
except AlexaError as err:
response = directive.error(
error_type=err.error_type,
error_message=err.error_message,
payload=err.payload,
)
except Exception: # pylint: disable=broad-except
_LOGGER.exception(
"Uncaught exception processing Alexa %s/%s request (%s)",
directive.namespace,
directive.name,
directive.entity_id or "-",
)
response = directive.error(error_message="Unknown error")
request_info = {"namespace": directive.namespace, "name": directive.name}
if directive.has_endpoint:
request_info["entity_id"] = directive.entity_id
hass.bus.async_fire(
EVENT_ALEXA_SMART_HOME,
{
"request": request_info,
"response": {"namespace": response.namespace, "name": response.name},
},
context=context,
)
return response.serialize()