core/homeassistant/components/intent_script.py

101 lines
2.9 KiB
Python
Raw Normal View History

"""Handle intents with scripts."""
import asyncio
import copy
import logging
import voluptuous as vol
from homeassistant.helpers import (
intent, template, script, config_validation as cv)
DOMAIN = 'intent_script'
CONF_INTENTS = 'intents'
CONF_SPEECH = 'speech'
CONF_ACTION = 'action'
CONF_CARD = 'card'
CONF_TYPE = 'type'
CONF_TITLE = 'title'
CONF_CONTENT = 'content'
CONF_TEXT = 'text'
CONF_ASYNC_ACTION = 'async_action'
DEFAULT_CONF_ASYNC_ACTION = False
CONFIG_SCHEMA = vol.Schema({
DOMAIN: {
cv.string: {
vol.Optional(CONF_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_ASYNC_ACTION,
default=DEFAULT_CONF_ASYNC_ACTION): cv.boolean,
vol.Optional(CONF_CARD): {
vol.Optional(CONF_TYPE, default='simple'): cv.string,
vol.Required(CONF_TITLE): cv.template,
vol.Required(CONF_CONTENT): cv.template,
},
vol.Optional(CONF_SPEECH): {
vol.Optional(CONF_TYPE, default='plain'): cv.string,
vol.Required(CONF_TEXT): cv.template,
}
}
}
}, extra=vol.ALLOW_EXTRA)
_LOGGER = logging.getLogger(__name__)
@asyncio.coroutine
def async_setup(hass, config):
"""Activate Alexa component."""
intents = copy.deepcopy(config[DOMAIN])
template.attach(hass, intents)
for intent_type, conf in intents.items():
if CONF_ACTION in conf:
conf[CONF_ACTION] = script.Script(
hass, conf[CONF_ACTION],
"Intent Script {}".format(intent_type))
intent.async_register(hass, ScriptIntentHandler(intent_type, conf))
return True
class ScriptIntentHandler(intent.IntentHandler):
"""Respond to an intent with a script."""
def __init__(self, intent_type, config):
"""Initialize the script intent handler."""
self.intent_type = intent_type
self.config = config
@asyncio.coroutine
def async_handle(self, intent_obj):
"""Handle the intent."""
speech = self.config.get(CONF_SPEECH)
card = self.config.get(CONF_CARD)
action = self.config.get(CONF_ACTION)
is_async_action = self.config.get(CONF_ASYNC_ACTION)
slots = {key: value['value'] for key, value
in intent_obj.slots.items()}
if action is not None:
if is_async_action:
intent_obj.hass.async_add_job(action.async_run(slots))
else:
yield from action.async_run(slots)
response = intent_obj.create_response()
if speech is not None:
response.async_set_speech(speech[CONF_TEXT].async_render(slots),
speech[CONF_TYPE])
if card is not None:
response.async_set_card(
card[CONF_TITLE].async_render(slots),
card[CONF_CONTENT].async_render(slots),
card[CONF_TYPE])
return response