Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions homeassistant/components/demo/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
COLOR_MODE_RGBW,
COLOR_MODE_RGBWW,
COLOR_MODE_WHITE,
SUPPORT_EFFECT,
LightEntity,
LightEntityFeature,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
Expand Down Expand Up @@ -149,7 +149,7 @@ def __init__(
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:
Expand Down
27 changes: 19 additions & 8 deletions homeassistant/components/light/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import csv
import dataclasses
from datetime import timedelta
from enum import IntEnum
import logging
import os
from typing import cast, final
Expand Down Expand Up @@ -40,7 +41,17 @@

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 CoverEntityFeature enum instead.
Comment thread
balloob marked this conversation as resolved.
Outdated
SUPPORT_BRIGHTNESS = 1 # Deprecated, replaced by color modes
SUPPORT_COLOR_TEMP = 2 # Deprecated, replaced by color modes
SUPPORT_EFFECT = 4
Expand Down Expand Up @@ -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)}
Expand All @@ -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)
Expand Down Expand Up @@ -831,7 +842,7 @@ def capability_attributes(self):
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)
Expand Down Expand Up @@ -927,7 +938,7 @@ def state_attributes(self):
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}
Expand Down
6 changes: 3 additions & 3 deletions homeassistant/components/light/device_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
ATTR_FLASH,
DOMAIN,
FLASH_SHORT,
SUPPORT_FLASH,
VALID_BRIGHTNESS_PCT,
VALID_FLASH,
LightEntityFeature,
brightness_supported,
get_supported_color_modes,
)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {}
8 changes: 4 additions & 4 deletions tests/components/light/test_device_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
DOMAIN,
FLASH_LONG,
FLASH_SHORT,
SUPPORT_FLASH,
LightEntityFeature,
)
from homeassistant.const import CONF_PLATFORM, STATE_OFF, STATE_ON
from homeassistant.helpers import device_registry
Expand Down Expand Up @@ -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 = [
Expand Down Expand Up @@ -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,
{},
Expand All @@ -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,
{},
{
Expand Down
16 changes: 9 additions & 7 deletions tests/components/light/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
)
Expand Down Expand Up @@ -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,
Expand Down