def test_deprecated_api_clear_completed(hass, hass_client, sl_setup): """Test the API.""" yield from intent.async_handle(hass, "test", "HassShoppingListAddItem", {"item": { "value": "beer" }}) yield from intent.async_handle(hass, "test", "HassShoppingListAddItem", {"item": { "value": "wine" }}) beer_id = hass.data["shopping_list"].items[0]["id"] wine_id = hass.data["shopping_list"].items[1]["id"] client = yield from hass_client() # Mark beer as completed resp = yield from client.post("/api/shopping_list/item/{}".format(beer_id), json={"complete": True}) assert resp.status == 200 resp = yield from client.post("/api/shopping_list/clear_completed") assert resp.status == 200 items = hass.data["shopping_list"].items assert len(items) == 1 assert items[0] == {"id": wine_id, "name": "wine", "complete": False}
def test_deprecated_api_update(hass, hass_client, sl_setup): """Test the API.""" yield from intent.async_handle(hass, "test", "HassShoppingListAddItem", {"item": { "value": "beer" }}) yield from intent.async_handle(hass, "test", "HassShoppingListAddItem", {"item": { "value": "wine" }}) beer_id = hass.data["shopping_list"].items[0]["id"] wine_id = hass.data["shopping_list"].items[1]["id"] client = yield from hass_client() resp = yield from client.post("/api/shopping_list/item/{}".format(beer_id), json={"name": "soda"}) assert resp.status == 200 data = yield from resp.json() assert data == {"id": beer_id, "name": "soda", "complete": False} resp = yield from client.post("/api/shopping_list/item/{}".format(wine_id), json={"complete": True}) assert resp.status == 200 data = yield from resp.json() assert data == {"id": wine_id, "name": "wine", "complete": True} beer, wine = hass.data["shopping_list"].items assert beer == {"id": beer_id, "name": "soda", "complete": False} assert wine == {"id": wine_id, "name": "wine", "complete": True}
def test_api_clear_completed(hass, test_client): """Test the API.""" yield from async_setup_component(hass, 'shopping_list', {}) yield from intent.async_handle( hass, 'test', 'HassShoppingListAddItem', {'item': {'value': 'beer'}} ) yield from intent.async_handle( hass, 'test', 'HassShoppingListAddItem', {'item': {'value': 'wine'}} ) beer_id = hass.data['shopping_list'].items[0]['id'] wine_id = hass.data['shopping_list'].items[1]['id'] client = yield from test_client(hass.http.app) # Mark beer as completed resp = yield from client.post( '/api/shopping_list/item/{}'.format(beer_id), json={ 'complete': True }) assert resp.status == 200 resp = yield from client.post('/api/shopping_list/clear_completed') assert resp.status == 200 items = hass.data['shopping_list'].items assert len(items) == 1 assert items[0] == { 'id': wine_id, 'name': 'wine', 'complete': False }
def test_deprecated_api_update(hass, hass_client): """Test the API.""" yield from async_setup_component(hass, 'shopping_list', {}) yield from intent.async_handle(hass, 'test', 'HassShoppingListAddItem', {'item': { 'value': 'beer' }}) yield from intent.async_handle(hass, 'test', 'HassShoppingListAddItem', {'item': { 'value': 'wine' }}) beer_id = hass.data['shopping_list'].items[0]['id'] wine_id = hass.data['shopping_list'].items[1]['id'] client = yield from hass_client() resp = yield from client.post('/api/shopping_list/item/{}'.format(beer_id), json={'name': 'soda'}) assert resp.status == 200 data = yield from resp.json() assert data == {'id': beer_id, 'name': 'soda', 'complete': False} resp = yield from client.post('/api/shopping_list/item/{}'.format(wine_id), json={'complete': True}) assert resp.status == 200 data = yield from resp.json() assert data == {'id': wine_id, 'name': 'wine', 'complete': True} beer, wine = hass.data['shopping_list'].items assert beer == {'id': beer_id, 'name': 'soda', 'complete': False} assert wine == {'id': wine_id, 'name': 'wine', 'complete': True}
def test_api_update(hass, test_client): """Test the API.""" yield from async_setup_component(hass, 'shopping_list', {}) yield from intent.async_handle( hass, 'test', 'HassShoppingListAddItem', {'item': {'value': 'beer'}} ) yield from intent.async_handle( hass, 'test', 'HassShoppingListAddItem', {'item': {'value': 'wine'}} ) beer_id = hass.data['shopping_list'].items[0]['id'] wine_id = hass.data['shopping_list'].items[1]['id'] client = yield from test_client(hass.http.app) resp = yield from client.post( '/api/shopping_list/item/{}'.format(beer_id), json={ 'name': 'soda' }) assert resp.status == 200 data = yield from resp.json() assert data == { 'id': beer_id, 'name': 'soda', 'complete': False } resp = yield from client.post( '/api/shopping_list/item/{}'.format(wine_id), json={ 'complete': True }) assert resp.status == 200 data = yield from resp.json() assert data == { 'id': wine_id, 'name': 'wine', 'complete': True } beer, wine = hass.data['shopping_list'].items assert beer == { 'id': beer_id, 'name': 'soda', 'complete': False } assert wine == { 'id': wine_id, 'name': 'wine', 'complete': True }
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: %s.", intent_type)
def test_intent_script(hass): """Test intent scripts work.""" calls = async_mock_service(hass, 'test', 'service') yield from async_setup_component(hass, 'intent_script', { 'intent_script': { 'HelloWorld': { 'action': { 'service': 'test.service', 'data_template': { 'hello': '{{ name }}' } }, 'card': { 'title': 'Hello {{ name }}', 'content': 'Content for {{ name }}', }, 'speech': { 'text': 'Good morning {{ name }}' } } } }) response = yield from intent.async_handle( hass, 'test', 'HelloWorld', {'name': {'value': 'Paulus'}} ) assert len(calls) == 1 assert calls[0].data['hello'] == 'Paulus' assert response.speech['plain']['speech'] == 'Good morning Paulus' assert response.card['simple']['title'] == 'Hello Paulus' assert response.card['simple']['content'] == 'Content for Paulus'
def test_turn_on_multiple_intent(hass): """Test HassTurnOn intent with multiple similar entities. This tests that matching finds the proper entity among similar names. """ result = yield from comps.async_setup(hass, {}) assert result hass.states.async_set('light.test_light', 'off') hass.states.async_set('light.test_lights_2', 'off') hass.states.async_set('light.test_lighter', 'off') calls = async_mock_service(hass, 'light', SERVICE_TURN_ON) response = yield from intent.async_handle( hass, 'test', 'HassTurnOn', {'name': { 'value': 'test lights' }}) yield from hass.async_block_till_done() assert response.speech['plain']['speech'] == 'Turned test lights 2 on' assert len(calls) == 1 call = calls[0] assert call.domain == 'light' assert call.service == 'turn_on' assert call.data == {'entity_id': ['light.test_lights_2']}
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.")
def async_handle_message(hass, message): """Handle a DialogFlow message.""" req = message.get('result') action_incomplete = req['actionIncomplete'] if action_incomplete: return None action = req.get('action', '') parameters = req.get('parameters') dialogflow_response = DialogflowResponse(parameters) if action == "": raise DialogFlowError( "You have not defined an action in your Dialogflow intent.") intent_response = yield from intent.async_handle( hass, DOMAIN, action, {key: {'value': value} for key, value in parameters.items()}) if 'plain' in intent_response.speech: dialogflow_response.add_speech( intent_response.speech['plain']['speech']) return dialogflow_response.as_dict()
def test_add_item(hass, sl_setup): """Test adding an item intent.""" response = yield from intent.async_handle( hass, "test", "HassShoppingListAddItem", {"item": {"value": "beer"}} ) assert response.speech["plain"]["speech"] == "I've added beer to your shopping list"
def post(self, request): """Handle Dialogflow.""" hass = request.app['hass'] data = yield from request.json() _LOGGER.debug("Received Dialogflow request: %s", data) req = data.get('result') if req is None: _LOGGER.error("Received invalid data from Dialogflow: %s", data) return self.json_message("Expected result value not received", HTTP_BAD_REQUEST) action_incomplete = req['actionIncomplete'] if action_incomplete: return None action = req.get('action') parameters = req.get('parameters') dialogflow_response = DialogflowResponse(parameters) if action == "": _LOGGER.warning("Received intent with empty action") dialogflow_response.add_speech( "You have not defined an action in your Dialogflow intent.") return self.json(dialogflow_response) try: intent_response = yield from intent.async_handle( hass, DOMAIN, action, {key: { 'value': value } for key, value in parameters.items()}) except intent.UnknownIntent as err: _LOGGER.warning("Received unknown intent %s", action) dialogflow_response.add_speech( "This intent is not yet configured within Home Assistant.") return self.json(dialogflow_response) except intent.InvalidSlotInfo as err: _LOGGER.error("Received invalid slot data: %s", err) return self.json_message('Invalid slot data received', HTTP_BAD_REQUEST) except intent.IntentError: _LOGGER.exception("Error handling request for %s", action) return self.json_message('Error handling intent', HTTP_BAD_REQUEST) if 'plain' in intent_response.speech: dialogflow_response.add_speech( intent_response.speech['plain']['speech']) return self.json(dialogflow_response)
def test_add_item(hass): """Test adding an item intent.""" yield from async_setup_component(hass, 'shopping_list', {}) response = yield from intent.async_handle( hass, 'test', 'HassShoppingListAddItem', {'item': {'value': 'beer'}} ) assert response.speech['plain']['speech'] == \ "I've added beer to your shopping list"
def test_recent_items_intent(hass, sl_setup): """Test recent items.""" yield from intent.async_handle( hass, "test", "HassShoppingListAddItem", {"item": {"value": "beer"}} ) yield from intent.async_handle( hass, "test", "HassShoppingListAddItem", {"item": {"value": "wine"}} ) yield from intent.async_handle( hass, "test", "HassShoppingListAddItem", {"item": {"value": "soda"}} ) response = yield from intent.async_handle(hass, "test", "HassShoppingListLastItems") assert ( response.speech["plain"]["speech"] == "These are the top 3 items on your shopping list: soda, wine, beer" )
def post(self, request): """Handle API.AI.""" hass = request.app['hass'] data = yield from request.json() _LOGGER.debug("Received api.ai request: %s", data) req = data.get('result') if req is None: _LOGGER.error("Received invalid data from api.ai: %s", data) return self.json_message( "Expected result value not received", HTTP_BAD_REQUEST) action_incomplete = req['actionIncomplete'] if action_incomplete: return None action = req.get('action') parameters = req.get('parameters') apiai_response = ApiaiResponse(parameters) if action == "": _LOGGER.warning("Received intent with empty action") apiai_response.add_speech( "You have not defined an action in your api.ai intent.") return self.json(apiai_response) try: intent_response = yield from intent.async_handle( hass, DOMAIN, action, {key: {'value': value} for key, value in parameters.items()}) except intent.UnknownIntent as err: _LOGGER.warning('Received unknown intent %s', action) apiai_response.add_speech( "This intent is not yet configured within Home Assistant.") return self.json(apiai_response) except intent.InvalidSlotInfo as err: _LOGGER.error('Received invalid slot data: %s', err) return self.json_message('Invalid slot data received', HTTP_BAD_REQUEST) except intent.IntentError: _LOGGER.exception('Error handling request for %s', action) return self.json_message('Error handling intent', HTTP_BAD_REQUEST) if 'plain' in intent_response.speech: apiai_response.add_speech( intent_response.speech['plain']['speech']) return self.json(apiai_response)
def test_recent_items_intent(hass): """Test recent items.""" yield from async_setup_component(hass, 'shopping_list', {}) yield from intent.async_handle( hass, 'test', 'HassShoppingListAddItem', {'item': {'value': 'beer'}} ) yield from intent.async_handle( hass, 'test', 'HassShoppingListAddItem', {'item': {'value': 'wine'}} ) yield from intent.async_handle( hass, 'test', 'HassShoppingListAddItem', {'item': {'value': 'soda'}} ) response = yield from intent.async_handle( hass, 'test', 'HassShoppingListLastItems' ) assert response.speech['plain']['speech'] == \ "These are the top 3 items on your shopping list: soda, wine, beer"
def test_deprecated_api_get_all(hass, hass_client, sl_setup): """Test the API.""" yield from intent.async_handle( hass, "test", "HassShoppingListAddItem", {"item": {"value": "beer"}} ) yield from intent.async_handle( hass, "test", "HassShoppingListAddItem", {"item": {"value": "wine"}} ) client = yield from hass_client() resp = yield from client.get("/api/shopping_list") assert resp.status == 200 data = yield from resp.json() assert len(data) == 2 assert data[0]["name"] == "beer" assert not data[0]["complete"] assert data[1]["name"] == "wine" assert not data[1]["complete"]
def test_api_get_all(hass, test_client): """Test the API.""" yield from async_setup_component(hass, 'shopping_list', {}) yield from intent.async_handle( hass, 'test', 'HassShoppingListAddItem', {'item': {'value': 'beer'}} ) yield from intent.async_handle( hass, 'test', 'HassShoppingListAddItem', {'item': {'value': 'wine'}} ) client = yield from test_client(hass.http.app) resp = yield from client.get('/api/shopping_list') assert resp.status == 200 data = yield from resp.json() assert len(data) == 2 assert data[0]['name'] == 'beer' assert not data[0]['complete'] assert data[1]['name'] == 'wine' assert not data[1]['complete']
def _process(hass, text): """Process a line of text.""" intents = hass.data.get(DOMAIN, {}) for intent_type, matchers in intents.items(): for matcher in matchers: match = matcher.match(text) if not match: continue response = yield from intent.async_handle( hass, DOMAIN, intent_type, {key: {'value': value} for key, value in match.groupdict().items()}, text) return response from fuzzywuzzy import process as fuzzyExtract text = text.lower() match = REGEX_TURN_COMMAND.match(text) if not match: _LOGGER.error("Unable to process: %s", text) return None name, command = match.groups() entities = {state.entity_id: state.name for state in hass.states.async_all()} entity_ids = fuzzyExtract.extractOne( name, entities, score_cutoff=65)[2] if not entity_ids: _LOGGER.error( "Could not find entity id %s from text %s", name, text) return None if command == 'on': yield from hass.services.async_call( core.DOMAIN, SERVICE_TURN_ON, { ATTR_ENTITY_ID: entity_ids, }, blocking=True) elif command == 'off': yield from hass.services.async_call( core.DOMAIN, SERVICE_TURN_OFF, { ATTR_ENTITY_ID: entity_ids, }, blocking=True) else: _LOGGER.error('Got unsupported command %s from text %s', command, text) return None
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 snips_response = None if request['intent']['intentName'].startswith('user_'): intent_type = request['intent']['intentName'].split('__')[-1] else: intent_type = request['intent']['intentName'].split(':')[-1] slots = {} for slot in request.get('slots', []): slots[slot['slotName']] = {'value': resolve_slot_values(slot)} try: intent_response = yield from intent.async_handle( hass, DOMAIN, intent_type, slots, request['input']) if 'plain' in intent_response.speech: snips_response = intent_response.speech['plain']['speech'] except intent.UnknownIntent as err: _LOGGER.warning("Received unknown intent %s", request['intent']['intentName']) #snips_response = "Unknown Intent" except intent.IntentError: _LOGGER.exception("Error while handling intent: %s.", intent_type) snips_response = "Error while handling intent" notification = { 'sessionId': request.get('sessionId', 'default'), 'text': snips_response } _LOGGER.debug("send_response %s", json.dumps(notification)) mqtt.async_publish(hass, 'hermes/dialogueManager/endSession', json.dumps(notification))
def test_api_update_fails(hass, hass_client, sl_setup): """Test the API.""" yield from intent.async_handle(hass, "test", "HassShoppingListAddItem", {"item": { "value": "beer" }}) client = yield from hass_client() resp = yield from client.post("/api/shopping_list/non_existing", json={"name": "soda"}) assert resp.status == 404 beer_id = hass.data["shopping_list"].items[0]["id"] resp = yield from client.post("/api/shopping_list/item/{}".format(beer_id), json={"name": 123}) assert resp.status == 400
def test_toggle_intent(hass): """Test HassToggle intent.""" result = yield from comps.async_setup(hass, {}) assert result hass.states.async_set('light.test_light', 'off') calls = async_mock_service(hass, 'light', SERVICE_TOGGLE) response = yield from intent.async_handle( hass, 'test', 'HassToggle', {'name': {'value': 'test light'}} ) yield from hass.async_block_till_done() assert response.speech['plain']['speech'] == 'Toggled test light' assert len(calls) == 1 call = calls[0] assert call.domain == 'light' assert call.service == 'toggle' assert call.data == {'entity_id': ['light.test_light']}
def async_handle_intent(hass, message): """Handle an intent request. Raises: - intent.UnknownIntent - intent.InvalidSlotInfo - intent.IntentError """ req = message.get('request') alexa_intent_info = req.get('intent') alexa_response = AlexaResponse(hass, alexa_intent_info) if req['type'] == 'LaunchRequest': intent_name = message.get('session', {}) \ .get('application', {}) \ .get('applicationId') else: intent_name = alexa_intent_info['name'] intent_response = yield from intent.async_handle( hass, DOMAIN, intent_name, { key: { 'value': value } for key, value in alexa_response.variables.items() }) for intent_speech, alexa_speech in SPEECH_MAPPINGS.items(): if intent_speech in intent_response.speech: alexa_response.add_speech( alexa_speech, intent_response.speech[intent_speech]['speech']) break if 'simple' in intent_response.card: alexa_response.add_card(CardType.simple, intent_response.card['simple']['title'], intent_response.card['simple']['content']) return alexa_response.as_dict()
def test_intent_script(hass): """Test intent scripts work.""" calls = async_mock_service(hass, "test", "service") yield from async_setup_component( hass, "intent_script", { "intent_script": { "HelloWorld": { "action": { "service": "test.service", "data_template": { "hello": "{{ name }}" }, }, "card": { "title": "Hello {{ name }}", "content": "Content for {{ name }}", }, "speech": { "text": "Good morning {{ name }}" }, } } }, ) response = yield from intent.async_handle(hass, "test", "HelloWorld", {"name": { "value": "Paulus" }}) assert len(calls) == 1 assert calls[0].data["hello"] == "Paulus" assert response.speech["plain"]["speech"] == "Good morning Paulus" assert response.card["simple"]["title"] == "Hello Paulus" assert response.card["simple"]["content"] == "Content for Paulus"
def test_api_update_fails(hass, hass_client): """Test the API.""" yield from async_setup_component(hass, 'shopping_list', {}) yield from intent.async_handle(hass, 'test', 'HassShoppingListAddItem', {'item': { 'value': 'beer' }}) client = yield from hass_client() resp = yield from client.post('/api/shopping_list/non_existing', json={'name': 'soda'}) assert resp.status == 404 beer_id = hass.data['shopping_list'].items[0]['id'] resp = yield from client.post('/api/shopping_list/item/{}'.format(beer_id), json={ 'name': 123, }) assert resp.status == 400
def async_handle_intent(hass, message): """Handle an intent request. Raises: - intent.UnknownIntent - intent.InvalidSlotInfo - intent.IntentError """ req = message.get('request') alexa_intent_info = req.get('intent') alexa_response = AlexaResponse(hass, alexa_intent_info) if req['type'] == 'LaunchRequest': intent_name = message.get('session', {}) \ .get('application', {}) \ .get('applicationId') else: intent_name = alexa_intent_info['name'] intent_response = yield from intent.async_handle( hass, DOMAIN, intent_name, {key: {'value': value} for key, value in alexa_response.variables.items()}) for intent_speech, alexa_speech in SPEECH_MAPPINGS.items(): if intent_speech in intent_response.speech: alexa_response.add_speech( alexa_speech, intent_response.speech[intent_speech]['speech']) break if 'simple' in intent_response.card: alexa_response.add_card( CardType.simple, intent_response.card['simple']['title'], intent_response.card['simple']['content']) return alexa_response.as_dict()
def test_api_update_fails(hass, test_client): """Test the API.""" yield from async_setup_component(hass, 'shopping_list', {}) yield from intent.async_handle( hass, 'test', 'HassShoppingListAddItem', {'item': {'value': 'beer'}} ) client = yield from test_client(hass.http.app) resp = yield from client.post( '/api/shopping_list/non_existing', json={ 'name': 'soda' }) assert resp.status == 404 beer_id = hass.data['shopping_list'].items[0]['id'] resp = yield from client.post( '/api/shopping_list/item/{}'.format(beer_id), json={ 'name': 123, }) assert resp.status == 400
def test_turn_on_multiple_intent(hass): """Test HassTurnOn intent with multiple similar entities. This tests that matching finds the proper entity among similar names. """ result = yield from comps.async_setup(hass, {}) assert result hass.states.async_set('light.test_light', 'off') hass.states.async_set('light.test_lights_2', 'off') hass.states.async_set('light.test_lighter', 'off') calls = async_mock_service(hass, 'light', SERVICE_TURN_ON) response = yield from intent.async_handle( hass, 'test', 'HassTurnOn', {'name': {'value': 'test lights'}} ) yield from hass.async_block_till_done() assert response.speech['plain']['speech'] == 'Turned test lights 2 on' assert len(calls) == 1 call = calls[0] assert call.domain == 'light' assert call.service == 'turn_on' assert call.data == {'entity_id': ['light.test_lights_2']}
def async_parse(call): message = call.data[ATTR_MESSAGE] project_name = call.data[ATTR_PROJECT_NAME] # idle -> thinking hass.states.async_set(OBJECT_RECOGNIZER, STATE_THINKING, state_attrs) # Run parsing in a separate thread result = {} parse_event = threading.Event() def parse(): nonlocal result result = hass.data[DOMAIN].parse(message, project_name) parse_event.set() thread = threading.Thread(target=parse, daemon=True) thread.start() loop = asyncio.get_event_loop() yield from loop.run_in_executor(None, parse_event.wait) # Deconstruct result intent_type = '' if 'intent' in result: intent_type = result['intent']['name'] slots = {} if 'entities' in result: # This will unfortunately only allow for one value per entity (slot). # rasaNLU supports multiple values per slot, but hass doesn't seem to. for entity_value in result['entities']: slots[entity_value['entity']] = { 'value': entity_value['value'] } try: # Try to handle the intent with hass yield from intent.async_handle(hass, DOMAIN, intent_type, slots=slots, text_input=message) # Fire known intent event hass.bus.async_fire( EVENT_KNOWN_INTENT, { 'name': name, # name of the component 'intent_type': intent_type, # type of intent 'slots': slots, # slots and values 'message': message # text provided }) except: # Fire unknown intent event hass.bus.async_fire( EVENT_UNKNOWN_INTENT, { 'name': name, # name of the component 'message': message # text provided }) state_attrs['intent'] = intent_type # thinking -> idle hass.states.async_set(OBJECT_RECOGNIZER, STATE_IDLE, state_attrs)
def post(self, request): """Handle Alexa.""" hass = request.app['hass'] data = yield from request.json() _LOGGER.debug('Received Alexa request: %s', data) req = data.get('request') if req is None: _LOGGER.error('Received invalid data from Alexa: %s', data) return self.json_message('Expected request value not received', HTTP_BAD_REQUEST) req_type = req['type'] if req_type == 'SessionEndedRequest': return None alexa_intent_info = req.get('intent') alexa_response = AlexaResponse(hass, alexa_intent_info) if req_type != 'IntentRequest' and req_type != 'LaunchRequest': _LOGGER.warning('Received unsupported request: %s', req_type) return self.json_message( 'Received unsupported request: {}'.format(req_type), HTTP_BAD_REQUEST) if req_type == 'LaunchRequest': intent_name = data.get('session', {}) \ .get('application', {}) \ .get('applicationId') else: intent_name = alexa_intent_info['name'] try: intent_response = yield from intent.async_handle( hass, DOMAIN, intent_name, {key: {'value': value} for key, value in alexa_response.variables.items()}) except intent.UnknownIntent as err: _LOGGER.warning('Received unknown intent %s', intent_name) alexa_response.add_speech( SpeechType.plaintext, "This intent is not yet configured within Home Assistant.") return self.json(alexa_response) except intent.InvalidSlotInfo as err: _LOGGER.error('Received invalid slot data from Alexa: %s', err) return self.json_message('Invalid slot data received', HTTP_BAD_REQUEST) except intent.IntentError: _LOGGER.exception('Error handling request for %s', intent_name) return self.json_message('Error handling intent', HTTP_BAD_REQUEST) for intent_speech, alexa_speech in SPEECH_MAPPINGS.items(): if intent_speech in intent_response.speech: alexa_response.add_speech( alexa_speech, intent_response.speech[intent_speech]['speech']) break if 'simple' in intent_response.card: alexa_response.add_card( CardType.simple, intent_response.card['simple']['title'], intent_response.card['simple']['content']) return self.json(alexa_response)