hass-core/homeassistant/components/snips.py
Paulus Schoutsen 7edf14e55f Add Intent component (#8434)
* Add intent component

* Add intent script component

* Add shopping list component

* Convert Snips to use intent component

* Convert Alexa to use intent component

* Lint

* Fix Alexa tests

* Update snips test

* Add intent support to conversation

* Add API to view shopping list contents

* Lint

* Fix demo test

* Lint

* lint

* Remove type from slot schema

* Add dependency to conversation

* Move intent to be a helper

* Fix conversation

* Clean up intent helper

* Fix Alexa

* Snips to use new hass.components

* Allow registering intents with conversation at any point in time

* Shopping list to register sentences

* Add HTTP endpoint to Conversation

* Add async action option to intent_script

* Update API.ai to use intents

* Cleanup Alexa

* Shopping list component to register built-in panel

* Rename shopping list intent to inlude Hass name
2017-07-21 21:38:53 -07:00

74 lines
2 KiB
Python

"""
Support for Snips on-device ASR and NLU.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/snips/
"""
import asyncio
import json
import logging
import voluptuous as vol
from homeassistant.helpers import intent, config_validation as cv
DOMAIN = 'snips'
DEPENDENCIES = ['mqtt']
CONF_INTENTS = 'intents'
CONF_ACTION = 'action'
INTENT_TOPIC = 'hermes/nlu/intentParsed'
_LOGGER = logging.getLogger(__name__)
CONFIG_SCHEMA = vol.Schema({
DOMAIN: {}
}, extra=vol.ALLOW_EXTRA)
INTENT_SCHEMA = vol.Schema({
vol.Required('input'): str,
vol.Required('intent'): {
vol.Required('intentName'): str
},
vol.Optional('slots'): [{
vol.Required('slotName'): str,
vol.Required('value'): {
vol.Required('kind'): str,
vol.Required('value'): cv.match_all
}
}]
}, extra=vol.ALLOW_EXTRA)
@asyncio.coroutine
def async_setup(hass, config):
"""Activate Snips component."""
@asyncio.coroutine
def message_received(topic, payload, qos):
"""Handle new messages on MQTT."""
_LOGGER.debug("New intent: %s", payload)
try:
request = json.loads(payload)
except TypeError:
_LOGGER.error('Received invalid JSON: %s', payload)
return
try:
request = INTENT_SCHEMA(request)
except vol.Invalid as err:
_LOGGER.error('Intent has invalid schema: %s. %s', err, request)
return
intent_type = request['intent']['intentName'].split('__')[-1]
slots = {slot['slotName']: {'value': slot['value']['value']}
for slot in request.get('slots', [])}
try:
yield from intent.async_handle(
hass, DOMAIN, intent_type, slots, request['input'])
except intent.IntentError:
_LOGGER.exception("Error while handling intent.")
yield from hass.components.mqtt.async_subscribe(
INTENT_TOPIC, message_received)
return True