Add EntityFeature enum to Light (#69103)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>pull/69165/head
parent
2d37066ce5
commit
ea148a1b8e
|
@ -16,8 +16,8 @@ from homeassistant.components.light import (
|
||||||
COLOR_MODE_RGBW,
|
COLOR_MODE_RGBW,
|
||||||
COLOR_MODE_RGBWW,
|
COLOR_MODE_RGBWW,
|
||||||
COLOR_MODE_WHITE,
|
COLOR_MODE_WHITE,
|
||||||
SUPPORT_EFFECT,
|
|
||||||
LightEntity,
|
LightEntity,
|
||||||
|
LightEntityFeature,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
@ -149,7 +149,7 @@ class DemoLight(LightEntity):
|
||||||
supported_color_modes = SUPPORT_DEMO
|
supported_color_modes = SUPPORT_DEMO
|
||||||
self._color_modes = supported_color_modes
|
self._color_modes = supported_color_modes
|
||||||
if self._effect_list is not None:
|
if self._effect_list is not None:
|
||||||
self._features |= SUPPORT_EFFECT
|
self._features |= LightEntityFeature.EFFECT
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_info(self) -> DeviceInfo:
|
def device_info(self) -> DeviceInfo:
|
||||||
|
|
|
@ -5,6 +5,7 @@ from collections.abc import Iterable
|
||||||
import csv
|
import csv
|
||||||
import dataclasses
|
import dataclasses
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
from enum import IntEnum
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
from typing import cast, final
|
from typing import cast, final
|
||||||
|
@ -40,7 +41,17 @@ DATA_PROFILES = "light_profiles"
|
||||||
|
|
||||||
ENTITY_ID_FORMAT = DOMAIN + ".{}"
|
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_BRIGHTNESS = 1 # Deprecated, replaced by color modes
|
||||||
SUPPORT_COLOR_TEMP = 2 # Deprecated, replaced by color modes
|
SUPPORT_COLOR_TEMP = 2 # Deprecated, replaced by color modes
|
||||||
SUPPORT_EFFECT = 4
|
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."""
|
"""Filter out params not used in turn off or not supported by the light."""
|
||||||
supported_features = light.supported_features
|
supported_features = light.supported_features
|
||||||
|
|
||||||
if not supported_features & SUPPORT_FLASH:
|
if not supported_features & LightEntityFeature.FLASH:
|
||||||
params.pop(ATTR_FLASH, None)
|
params.pop(ATTR_FLASH, None)
|
||||||
if not supported_features & SUPPORT_TRANSITION:
|
if not supported_features & LightEntityFeature.TRANSITION:
|
||||||
params.pop(ATTR_TRANSITION, None)
|
params.pop(ATTR_TRANSITION, None)
|
||||||
|
|
||||||
return {k: v for k, v in params.items() if k in (ATTR_TRANSITION, ATTR_FLASH)}
|
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."""
|
"""Filter out params not supported by the light."""
|
||||||
supported_features = light.supported_features
|
supported_features = light.supported_features
|
||||||
|
|
||||||
if not supported_features & SUPPORT_EFFECT:
|
if not supported_features & LightEntityFeature.EFFECT:
|
||||||
params.pop(ATTR_EFFECT, None)
|
params.pop(ATTR_EFFECT, None)
|
||||||
if not supported_features & SUPPORT_FLASH:
|
if not supported_features & LightEntityFeature.FLASH:
|
||||||
params.pop(ATTR_FLASH, None)
|
params.pop(ATTR_FLASH, None)
|
||||||
if not supported_features & SUPPORT_TRANSITION:
|
if not supported_features & LightEntityFeature.TRANSITION:
|
||||||
params.pop(ATTR_TRANSITION, None)
|
params.pop(ATTR_TRANSITION, None)
|
||||||
if not supported_features & SUPPORT_WHITE_VALUE:
|
if not supported_features & SUPPORT_WHITE_VALUE:
|
||||||
params.pop(ATTR_WHITE_VALUE, None)
|
params.pop(ATTR_WHITE_VALUE, None)
|
||||||
|
@ -831,7 +842,7 @@ class LightEntity(ToggleEntity):
|
||||||
data[ATTR_MIN_MIREDS] = self.min_mireds
|
data[ATTR_MIN_MIREDS] = self.min_mireds
|
||||||
data[ATTR_MAX_MIREDS] = self.max_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_EFFECT_LIST] = self.effect_list
|
||||||
|
|
||||||
data[ATTR_SUPPORTED_COLOR_MODES] = sorted(supported_color_modes)
|
data[ATTR_SUPPORTED_COLOR_MODES] = sorted(supported_color_modes)
|
||||||
|
@ -927,7 +938,7 @@ class LightEntity(ToggleEntity):
|
||||||
if self.hs_color is not None:
|
if self.hs_color is not None:
|
||||||
data.update(self._light_internal_convert_color(COLOR_MODE_HS))
|
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
|
data[ATTR_EFFECT] = self.effect
|
||||||
|
|
||||||
return {key: val for key, val in data.items() if val is not None}
|
return {key: val for key, val in data.items() if val is not None}
|
||||||
|
|
|
@ -24,9 +24,9 @@ from . import (
|
||||||
ATTR_FLASH,
|
ATTR_FLASH,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
FLASH_SHORT,
|
FLASH_SHORT,
|
||||||
SUPPORT_FLASH,
|
|
||||||
VALID_BRIGHTNESS_PCT,
|
VALID_BRIGHTNESS_PCT,
|
||||||
VALID_FLASH,
|
VALID_FLASH,
|
||||||
|
LightEntityFeature,
|
||||||
brightness_supported,
|
brightness_supported,
|
||||||
get_supported_color_modes,
|
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})
|
actions.append({**base_action, CONF_TYPE: TYPE_FLASH})
|
||||||
|
|
||||||
return actions
|
return actions
|
||||||
|
@ -144,7 +144,7 @@ async def async_get_action_capabilities(
|
||||||
if brightness_supported(supported_color_modes):
|
if brightness_supported(supported_color_modes):
|
||||||
extra_fields[vol.Optional(ATTR_BRIGHTNESS_PCT)] = VALID_BRIGHTNESS_PCT
|
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
|
extra_fields[vol.Optional(ATTR_FLASH)] = VALID_FLASH
|
||||||
|
|
||||||
return {"extra_fields": vol.Schema(extra_fields)} if extra_fields else {}
|
return {"extra_fields": vol.Schema(extra_fields)} if extra_fields else {}
|
||||||
|
|
|
@ -9,7 +9,7 @@ from homeassistant.components.light import (
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
FLASH_LONG,
|
FLASH_LONG,
|
||||||
FLASH_SHORT,
|
FLASH_SHORT,
|
||||||
SUPPORT_FLASH,
|
LightEntityFeature,
|
||||||
)
|
)
|
||||||
from homeassistant.const import CONF_PLATFORM, STATE_OFF, STATE_ON
|
from homeassistant.const import CONF_PLATFORM, STATE_OFF, STATE_ON
|
||||||
from homeassistant.helpers import device_registry
|
from homeassistant.helpers import device_registry
|
||||||
|
@ -57,7 +57,7 @@ async def test_get_actions(hass, device_reg, entity_reg):
|
||||||
"test",
|
"test",
|
||||||
"5678",
|
"5678",
|
||||||
device_id=device_entry.id,
|
device_id=device_entry.id,
|
||||||
supported_features=SUPPORT_FLASH,
|
supported_features=LightEntityFeature.FLASH,
|
||||||
capabilities={"supported_color_modes": ["brightness"]},
|
capabilities={"supported_color_modes": ["brightness"]},
|
||||||
)
|
)
|
||||||
expected_actions = [
|
expected_actions = [
|
||||||
|
@ -196,7 +196,7 @@ async def test_get_action_capabilities(hass, device_reg, entity_reg):
|
||||||
(
|
(
|
||||||
False,
|
False,
|
||||||
{"turn_on", "toggle", "turn_off", "flash"},
|
{"turn_on", "toggle", "turn_off", "flash"},
|
||||||
SUPPORT_FLASH,
|
LightEntityFeature.FLASH,
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
{},
|
{},
|
||||||
|
@ -215,7 +215,7 @@ async def test_get_action_capabilities(hass, device_reg, entity_reg):
|
||||||
True,
|
True,
|
||||||
{"turn_on", "toggle", "turn_off", "flash"},
|
{"turn_on", "toggle", "turn_off", "flash"},
|
||||||
0,
|
0,
|
||||||
SUPPORT_FLASH,
|
LightEntityFeature.FLASH,
|
||||||
None,
|
None,
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
|
|
|
@ -120,14 +120,16 @@ async def test_services(hass, mock_light_profiles, enable_custom_integrations):
|
||||||
ent1, ent2, ent3 = platform.ENTITIES
|
ent1, ent2, ent3 = platform.ENTITIES
|
||||||
ent1.supported_color_modes = [light.COLOR_MODE_HS]
|
ent1.supported_color_modes = [light.COLOR_MODE_HS]
|
||||||
ent3.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 = (
|
ent2.supported_features = (
|
||||||
light.SUPPORT_COLOR
|
light.SUPPORT_COLOR
|
||||||
| light.SUPPORT_EFFECT
|
| light.LightEntityFeature.EFFECT
|
||||||
| light.SUPPORT_TRANSITION
|
| light.LightEntityFeature.TRANSITION
|
||||||
| light.SUPPORT_WHITE_VALUE
|
| light.SUPPORT_WHITE_VALUE
|
||||||
)
|
)
|
||||||
ent3.supported_features = light.SUPPORT_FLASH | light.SUPPORT_TRANSITION
|
ent3.supported_features = (
|
||||||
|
light.LightEntityFeature.FLASH | light.LightEntityFeature.TRANSITION
|
||||||
|
)
|
||||||
|
|
||||||
# Test init
|
# Test init
|
||||||
assert light.is_on(hass, ent1.entity_id)
|
assert light.is_on(hass, ent1.entity_id)
|
||||||
|
@ -539,7 +541,7 @@ async def test_light_profiles(
|
||||||
|
|
||||||
ent1, _, _ = platform.ENTITIES
|
ent1, _, _ = platform.ENTITIES
|
||||||
ent1.supported_color_modes = [light.COLOR_MODE_HS]
|
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(
|
await hass.services.async_call(
|
||||||
light.DOMAIN,
|
light.DOMAIN,
|
||||||
|
@ -576,7 +578,7 @@ async def test_default_profiles_group(
|
||||||
|
|
||||||
ent, _, _ = platform.ENTITIES
|
ent, _, _ = platform.ENTITIES
|
||||||
ent.supported_color_modes = [light.COLOR_MODE_HS]
|
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(
|
await hass.services.async_call(
|
||||||
light.DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ent.entity_id}, blocking=True
|
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 = next(filter(lambda x: x.entity_id == "light.ceiling_2", platform.ENTITIES))
|
||||||
dev.supported_color_modes = [light.COLOR_MODE_HS]
|
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(
|
await hass.services.async_call(
|
||||||
light.DOMAIN,
|
light.DOMAIN,
|
||||||
SERVICE_TURN_ON,
|
SERVICE_TURN_ON,
|
||||||
|
|
Loading…
Reference in New Issue