"""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