From 80bc15e24b5c5665aa26ece36630dc6d6badc9de Mon Sep 17 00:00:00 2001 From: Bram Kragten <mail@bramkragten.nl> Date: Fri, 27 Sep 2019 21:51:46 +0200 Subject: [PATCH] Update Alexa discovery description (#26933) * Update Alexa discovery description * Update description * Fix test * Filter special chars --- homeassistant/components/alexa/entities.py | 20 +++++++++++++------- tests/components/alexa/test_smart_home.py | 18 +++++++++++++----- tests/components/cloud/test_client.py | 2 +- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/homeassistant/components/alexa/entities.py b/homeassistant/components/alexa/entities.py index 03d153f5927..f0d72af23d5 100644 --- a/homeassistant/components/alexa/entities.py +++ b/homeassistant/components/alexa/entities.py @@ -52,6 +52,8 @@ from .capabilities import ( ENTITY_ADAPTERS = Registry() +TRANSLATION_TABLE = dict.fromkeys(map(ord, r"}{\/|\"()[]+~!><*%"), None) + class DisplayCategory: """Possible display categories for Discovery response. @@ -134,15 +136,18 @@ class AlexaEntity: def friendly_name(self): """Return the Alexa API friendly name.""" - return self.entity_conf.get(CONF_NAME, self.entity.name) + return self.entity_conf.get(CONF_NAME, self.entity.name).translate( + TRANSLATION_TABLE + ) def description(self): """Return the Alexa API description.""" - return self.entity_conf.get(CONF_DESCRIPTION, self.entity.entity_id) + description = self.entity_conf.get(CONF_DESCRIPTION) or self.entity_id + return f"{description} via Home Assistant".translate(TRANSLATION_TABLE) def alexa_id(self): """Return the Alexa API entity id.""" - return self.entity.entity_id.replace(".", "#") + return self.entity.entity_id.replace(".", "#").translate(TRANSLATION_TABLE) def display_categories(self): """Return a list of display categories.""" @@ -389,10 +394,11 @@ class SceneCapabilities(AlexaEntity): """Class to represent Scene capabilities.""" def description(self): - """Return the description of the entity.""" - # Required description as per Amazon Scene docs - scene_fmt = "{} (Scene connected via Home Assistant)" - return scene_fmt.format(AlexaEntity.description(self)) + """Return the Alexa API description.""" + description = AlexaEntity.description(self) + if "scene" not in description.casefold(): + return f"{description} (Scene)" + return description def default_display_categories(self): """Return the display categories for this entity.""" diff --git a/tests/components/alexa/test_smart_home.py b/tests/components/alexa/test_smart_home.py index bd5a4d25edd..3cafa899024 100644 --- a/tests/components/alexa/test_smart_home.py +++ b/tests/components/alexa/test_smart_home.py @@ -1162,14 +1162,16 @@ async def test_entity_config(hass): request = get_new_request("Alexa.Discovery", "Discover") hass.states.async_set("light.test_1", "on", {"friendly_name": "Test light 1"}) + hass.states.async_set("scene.test_1", "scening", {"friendly_name": "Test 1"}) alexa_config = MockConfig(hass) alexa_config.entity_config = { "light.test_1": { - "name": "Config name", + "name": "Config *name*", "display_categories": "SWITCH", - "description": "Config description", - } + "description": "Config >!<description", + }, + "scene.test_1": {"description": "Config description"}, } msg = await smart_home.async_handle_message(hass, alexa_config, request) @@ -1177,17 +1179,23 @@ async def test_entity_config(hass): assert "event" in msg msg = msg["event"] - assert len(msg["payload"]["endpoints"]) == 1 + assert len(msg["payload"]["endpoints"]) == 2 appliance = msg["payload"]["endpoints"][0] assert appliance["endpointId"] == "light#test_1" assert appliance["displayCategories"][0] == "SWITCH" assert appliance["friendlyName"] == "Config name" - assert appliance["description"] == "Config description" + assert appliance["description"] == "Config description via Home Assistant" assert_endpoint_capabilities( appliance, "Alexa.PowerController", "Alexa.EndpointHealth" ) + scene = msg["payload"]["endpoints"][1] + assert scene["endpointId"] == "scene#test_1" + assert scene["displayCategories"][0] == "SCENE_TRIGGER" + assert scene["friendlyName"] == "Test 1" + assert scene["description"] == "Config description via Home Assistant (Scene)" + async def test_logging_request(hass, events): """Test that we log requests.""" diff --git a/tests/components/cloud/test_client.py b/tests/components/cloud/test_client.py index 5c895f09dbb..b7ac5f4cffd 100644 --- a/tests/components/cloud/test_client.py +++ b/tests/components/cloud/test_client.py @@ -53,7 +53,7 @@ async def test_handler_alexa(hass): assert len(endpoints) == 1 device = endpoints[0] - assert device["description"] == "Config description" + assert device["description"] == "Config description via Home Assistant" assert device["friendlyName"] == "Config name" assert device["displayCategories"] == ["LIGHT"] assert device["manufacturerName"] == "Home Assistant"