core/homeassistant/components/alexa/smart_home.py

81 lines
2.1 KiB
Python

"""Support for alexa Smart Home Skill API."""
import logging
import homeassistant.core as ha
from .const import API_DIRECTIVE, API_HEADER
from .errors import (
AlexaError,
AlexaBridgeUnreachableError,
)
from .handlers import HANDLERS
from .messages import AlexaDirective
_LOGGER = logging.getLogger(__name__)
EVENT_ALEXA_SMART_HOME = 'alexa_smart_home'
async def async_handle_message(
hass,
config,
request,
context=None,
enabled=True,
):
"""Handle incoming API messages.
If enabled is False, the response to all messagess 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')
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)
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()