From ea148a1b8ea611b07b606a4bfef44f66db8b2582 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Sun, 3 Apr 2022 05:57:01 +0200 Subject: [PATCH] Add EntityFeature enum to Light (#69103) Co-authored-by: Paulus Schoutsen --- homeassistant/components/demo/light.py | 4 +-- homeassistant/components/light/__init__.py | 27 +++++++++++++------ .../components/light/device_action.py | 6 ++--- tests/components/light/test_device_action.py | 8 +++--- tests/components/light/test_init.py | 16 ++++++----- 5 files changed, 37 insertions(+), 24 deletions(-) diff --git a/homeassistant/components/demo/light.py b/homeassistant/components/demo/light.py index 9bb3a30686d..16c792a9fb9 100644 --- a/homeassistant/components/demo/light.py +++ b/homeassistant/components/demo/light.py @@ -16,8 +16,8 @@ from homeassistant.components.light import ( COLOR_MODE_RGBW, COLOR_MODE_RGBWW, COLOR_MODE_WHITE, - SUPPORT_EFFECT, LightEntity, + LightEntityFeature, ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant @@ -149,7 +149,7 @@ class DemoLight(LightEntity): supported_color_modes = SUPPORT_DEMO self._color_modes = supported_color_modes if self._effect_list is not None: - self._features |= SUPPORT_EFFECT + self._features |= LightEntityFeature.EFFECT @property def device_info(self) -> DeviceInfo: diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index 36588704c85..e458897d9e4 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -5,6 +5,7 @@ from collections.abc import Iterable import csv import dataclasses from datetime import timedelta +from enum import IntEnum import logging import os from typing import cast, final @@ -40,7 +41,17 @@ DATA_PROFILES = "light_profiles" ENTITY_ID_FORMAT = DOMAIN + ".{}" -# Bitfield of features supported by the light entity + +class LightEntityFeature(IntEnum): + """Supported features of the light entity.""" + + EFFECT = 4 + FLASH = 8 + TRANSITION = 32 + + +# These SUPPORT_* constants are deprecated as of Home Assistant 2022.5. +# Please use the LightEntityFeature enum instead. SUPPORT_BRIGHTNESS = 1 # Deprecated, replaced by color modes SUPPORT_COLOR_TEMP = 2 # Deprecated, replaced by color modes SUPPORT_EFFECT = 4 @@ -274,9 +285,9 @@ def filter_turn_off_params(light, params): """Filter out params not used in turn off or not supported by the light.""" supported_features = light.supported_features - if not supported_features & SUPPORT_FLASH: + if not supported_features & LightEntityFeature.FLASH: params.pop(ATTR_FLASH, None) - if not supported_features & SUPPORT_TRANSITION: + if not supported_features & LightEntityFeature.TRANSITION: params.pop(ATTR_TRANSITION, None) return {k: v for k, v in params.items() if k in (ATTR_TRANSITION, ATTR_FLASH)} @@ -286,11 +297,11 @@ def filter_turn_on_params(light, params): """Filter out params not supported by the light.""" supported_features = light.supported_features - if not supported_features & SUPPORT_EFFECT: + if not supported_features & LightEntityFeature.EFFECT: params.pop(ATTR_EFFECT, None) - if not supported_features & SUPPORT_FLASH: + if not supported_features & LightEntityFeature.FLASH: params.pop(ATTR_FLASH, None) - if not supported_features & SUPPORT_TRANSITION: + if not supported_features & LightEntityFeature.TRANSITION: params.pop(ATTR_TRANSITION, None) if not supported_features & SUPPORT_WHITE_VALUE: params.pop(ATTR_WHITE_VALUE, None) @@ -831,7 +842,7 @@ class LightEntity(ToggleEntity): data[ATTR_MIN_MIREDS] = self.min_mireds data[ATTR_MAX_MIREDS] = self.max_mireds - if supported_features & SUPPORT_EFFECT: + if supported_features & LightEntityFeature.EFFECT: data[ATTR_EFFECT_LIST] = self.effect_list data[ATTR_SUPPORTED_COLOR_MODES] = sorted(supported_color_modes) @@ -927,7 +938,7 @@ class LightEntity(ToggleEntity): if self.hs_color is not None: data.update(self._light_internal_convert_color(COLOR_MODE_HS)) - if supported_features & SUPPORT_EFFECT: + if supported_features & LightEntityFeature.EFFECT: data[ATTR_EFFECT] = self.effect return {key: val for key, val in data.items() if val is not None} diff --git a/homeassistant/components/light/device_action.py b/homeassistant/components/light/device_action.py index 16140b3a2b1..285e34ebe08 100644 --- a/homeassistant/components/light/device_action.py +++ b/homeassistant/components/light/device_action.py @@ -24,9 +24,9 @@ from . import ( ATTR_FLASH, DOMAIN, FLASH_SHORT, - SUPPORT_FLASH, VALID_BRIGHTNESS_PCT, VALID_FLASH, + LightEntityFeature, brightness_supported, get_supported_color_modes, ) @@ -116,7 +116,7 @@ async def async_get_actions( ) ) - if supported_features & SUPPORT_FLASH: + if supported_features & LightEntityFeature.FLASH: actions.append({**base_action, CONF_TYPE: TYPE_FLASH}) return actions @@ -144,7 +144,7 @@ async def async_get_action_capabilities( if brightness_supported(supported_color_modes): extra_fields[vol.Optional(ATTR_BRIGHTNESS_PCT)] = VALID_BRIGHTNESS_PCT - if supported_features & SUPPORT_FLASH: + if supported_features & LightEntityFeature.FLASH: extra_fields[vol.Optional(ATTR_FLASH)] = VALID_FLASH return {"extra_fields": vol.Schema(extra_fields)} if extra_fields else {} diff --git a/tests/components/light/test_device_action.py b/tests/components/light/test_device_action.py index ec47710a6f6..be6c1c833bf 100644 --- a/tests/components/light/test_device_action.py +++ b/tests/components/light/test_device_action.py @@ -9,7 +9,7 @@ from homeassistant.components.light import ( DOMAIN, FLASH_LONG, FLASH_SHORT, - SUPPORT_FLASH, + LightEntityFeature, ) from homeassistant.const import CONF_PLATFORM, STATE_OFF, STATE_ON from homeassistant.helpers import device_registry @@ -57,7 +57,7 @@ async def test_get_actions(hass, device_reg, entity_reg): "test", "5678", device_id=device_entry.id, - supported_features=SUPPORT_FLASH, + supported_features=LightEntityFeature.FLASH, capabilities={"supported_color_modes": ["brightness"]}, ) expected_actions = [ @@ -196,7 +196,7 @@ async def test_get_action_capabilities(hass, device_reg, entity_reg): ( False, {"turn_on", "toggle", "turn_off", "flash"}, - SUPPORT_FLASH, + LightEntityFeature.FLASH, 0, None, {}, @@ -215,7 +215,7 @@ async def test_get_action_capabilities(hass, device_reg, entity_reg): True, {"turn_on", "toggle", "turn_off", "flash"}, 0, - SUPPORT_FLASH, + LightEntityFeature.FLASH, None, {}, { diff --git a/tests/components/light/test_init.py b/tests/components/light/test_init.py index 640a4b4533b..5819a63ebfe 100644 --- a/tests/components/light/test_init.py +++ b/tests/components/light/test_init.py @@ -120,14 +120,16 @@ async def test_services(hass, mock_light_profiles, enable_custom_integrations): ent1, ent2, ent3 = platform.ENTITIES ent1.supported_color_modes = [light.COLOR_MODE_HS] ent3.supported_color_modes = [light.COLOR_MODE_HS] - ent1.supported_features = light.SUPPORT_TRANSITION + ent1.supported_features = light.LightEntityFeature.TRANSITION ent2.supported_features = ( light.SUPPORT_COLOR - | light.SUPPORT_EFFECT - | light.SUPPORT_TRANSITION + | light.LightEntityFeature.EFFECT + | light.LightEntityFeature.TRANSITION | light.SUPPORT_WHITE_VALUE ) - ent3.supported_features = light.SUPPORT_FLASH | light.SUPPORT_TRANSITION + ent3.supported_features = ( + light.LightEntityFeature.FLASH | light.LightEntityFeature.TRANSITION + ) # Test init assert light.is_on(hass, ent1.entity_id) @@ -539,7 +541,7 @@ async def test_light_profiles( ent1, _, _ = platform.ENTITIES ent1.supported_color_modes = [light.COLOR_MODE_HS] - ent1.supported_features = light.SUPPORT_TRANSITION + ent1.supported_features = light.LightEntityFeature.TRANSITION await hass.services.async_call( light.DOMAIN, @@ -576,7 +578,7 @@ async def test_default_profiles_group( ent, _, _ = platform.ENTITIES ent.supported_color_modes = [light.COLOR_MODE_HS] - ent.supported_features = light.SUPPORT_TRANSITION + ent.supported_features = light.LightEntityFeature.TRANSITION await hass.services.async_call( light.DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ent.entity_id}, blocking=True ) @@ -683,7 +685,7 @@ async def test_default_profiles_light( dev = next(filter(lambda x: x.entity_id == "light.ceiling_2", platform.ENTITIES)) dev.supported_color_modes = [light.COLOR_MODE_HS] - dev.supported_features = light.SUPPORT_TRANSITION + dev.supported_features = light.LightEntityFeature.TRANSITION await hass.services.async_call( light.DOMAIN, SERVICE_TURN_ON,