From cf4b6307ae177d50eca856d6c5c6e6df06963e66 Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Wed, 2 Sep 2020 00:16:40 +1000 Subject: [PATCH] Provide compatibility with older Home Assistant installations. (#39539) Prior 0.113 all lights and switches were reported as dimmable devices and this was fixed by #37978. However, under some circumstances Alexa will not smoothly transition from those broken devices to the new ones as it cache the list of entities. It is imperative to have Alexa rediscover all devices and then remove the now non-responding duplicates using the Alexa phone App. This can take quite a while if you have lots of devices. An alternative would be to log to the Alexa web site and remove all the lights instead and then re-discover them all. If you have multiple echo devices on your network, it is possible that the entries would continue to show as duplicates. This is due to an individual echo devices caching the old list and re-using it. The only known solution for this is to remove your echo devices from your Amazon account and re-add them. After that, have Alexa rediscover all your devices. This is a one-off requirement. Fixes #39503 --- .../components/emulated_hue/__init__.py | 9 ++++++ .../components/emulated_hue/hue_api.py | 8 ++++- tests/components/emulated_hue/test_hue_api.py | 32 ++++++++++++++++++- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/emulated_hue/__init__.py b/homeassistant/components/emulated_hue/__init__.py index 5e50c727728..b4a49c7efcd 100644 --- a/homeassistant/components/emulated_hue/__init__.py +++ b/homeassistant/components/emulated_hue/__init__.py @@ -37,6 +37,7 @@ CONF_ENTITY_NAME = "name" CONF_EXPOSE_BY_DEFAULT = "expose_by_default" CONF_EXPOSED_DOMAINS = "exposed_domains" CONF_HOST_IP = "host_ip" +CONF_LIGHTS_ALL_DIMMABLE = "lights_all_dimmable" CONF_LISTEN_PORT = "listen_port" CONF_OFF_MAPS_TO_ON_DOMAINS = "off_maps_to_on_domains" CONF_TYPE = "type" @@ -45,6 +46,7 @@ CONF_UPNP_BIND_MULTICAST = "upnp_bind_multicast" TYPE_ALEXA = "alexa" TYPE_GOOGLE = "google_home" +DEFAULT_LIGHTS_ALL_DIMMABLE = False DEFAULT_LISTEN_PORT = 8300 DEFAULT_UPNP_BIND_MULTICAST = True DEFAULT_OFF_MAPS_TO_ON_DOMAINS = ["script", "scene"] @@ -84,6 +86,9 @@ CONFIG_SCHEMA = vol.Schema( vol.Optional(CONF_ENTITIES): vol.Schema( {cv.entity_id: CONFIG_ENTITY_SCHEMA} ), + vol.Optional( + CONF_LIGHTS_ALL_DIMMABLE, default=DEFAULT_LIGHTS_ALL_DIMMABLE + ): cv.boolean, } ) }, @@ -244,6 +249,10 @@ class Config: if hidden_value is not None: self._entities_with_hidden_attr_in_config[entity_id] = hidden_value + # Get whether all non-dimmable lights should be reported as dimmable + # for compatibility with older installations. + self.lights_all_dimmable = conf.get(CONF_LIGHTS_ALL_DIMMABLE) + def entity_id_to_number(self, entity_id): """Get a unique number for the entity id.""" if self.type == TYPE_ALEXA: diff --git a/homeassistant/components/emulated_hue/hue_api.py b/homeassistant/components/emulated_hue/hue_api.py index 0dd3d212dad..51580a28adf 100644 --- a/homeassistant/components/emulated_hue/hue_api.py +++ b/homeassistant/components/emulated_hue/hue_api.py @@ -774,12 +774,18 @@ def entity_to_json(config, entity): retval["type"] = "Dimmable light" retval["modelid"] = "HASS123" retval["state"].update({HUE_API_STATE_BRI: state[STATE_BRIGHTNESS]}) - else: + elif not config.lights_all_dimmable: # On/Off light (ZigBee Device ID: 0x0000) # Supports groups, scenes and on/off control retval["type"] = "On/Off light" retval["productname"] = "On/Off light" retval["modelid"] = "HASS321" + else: + # Dimmable light (Zigbee Device ID: 0x0100) + # Supports groups, scenes, on/off and dimming + # Reports fixed brightness for compatibility with Alexa. + retval["type"] = "Dimmable light" + retval["modelid"] = "HASS123" retval["state"].update({HUE_API_STATE_BRI: HUE_API_STATE_BRI_MAX}) return retval diff --git a/tests/components/emulated_hue/test_hue_api.py b/tests/components/emulated_hue/test_hue_api.py index 09791f9d242..0f61178107d 100644 --- a/tests/components/emulated_hue/test_hue_api.py +++ b/tests/components/emulated_hue/test_hue_api.py @@ -283,7 +283,37 @@ async def test_light_without_brightness_supported(hass_hue, hue_client): assert light_without_brightness_json["state"][HUE_API_STATE_ON] is True assert light_without_brightness_json["type"] == "On/Off light" - # BRI required for alexa compat + +async def test_lights_all_dimmable(hass, aiohttp_client): + """Test CONF_LIGHTS_ALL_DIMMABLE.""" + # create a lamp without brightness support + hass.states.async_set("light.no_brightness", "on", {}) + await setup.async_setup_component( + hass, http.DOMAIN, {http.DOMAIN: {http.CONF_SERVER_PORT: HTTP_SERVER_PORT}} + ) + await hass.async_block_till_done() + hue_config = { + emulated_hue.CONF_LISTEN_PORT: BRIDGE_SERVER_PORT, + emulated_hue.CONF_EXPOSE_BY_DEFAULT: True, + emulated_hue.CONF_LIGHTS_ALL_DIMMABLE: True, + } + with patch("homeassistant.components.emulated_hue.create_upnp_datagram_endpoint"): + await setup.async_setup_component( + hass, + emulated_hue.DOMAIN, + {emulated_hue.DOMAIN: hue_config}, + ) + await hass.async_block_till_done() + config = Config(None, hue_config) + config.numbers = ENTITY_IDS_BY_NUMBER + web_app = hass.http.app + HueOneLightStateView(config).register(web_app, web_app.router) + client = await aiohttp_client(web_app) + light_without_brightness_json = await perform_get_light_state( + client, "light.no_brightness", HTTP_OK + ) + assert light_without_brightness_json["state"][HUE_API_STATE_ON] is True + assert light_without_brightness_json["type"] == "Dimmable light" assert ( light_without_brightness_json["state"][HUE_API_STATE_BRI] == HUE_API_STATE_BRI_MAX