mirror of
https://github.com/home-assistant/core.git
synced 2025-06-18 20:17:07 +00:00
Fix Flash effect for Hue lights (#61733)
This commit is contained in:
parent
89a6640b82
commit
438d19f72b
@ -6,16 +6,19 @@ from typing import Any
|
|||||||
from aiohue.v2 import HueBridgeV2
|
from aiohue.v2 import HueBridgeV2
|
||||||
from aiohue.v2.controllers.events import EventType
|
from aiohue.v2.controllers.events import EventType
|
||||||
from aiohue.v2.controllers.groups import GroupedLight, Room, Zone
|
from aiohue.v2.controllers.groups import GroupedLight, Room, Zone
|
||||||
|
from aiohue.v2.models.feature import AlertEffectType
|
||||||
|
|
||||||
from homeassistant.components.light import (
|
from homeassistant.components.light import (
|
||||||
ATTR_BRIGHTNESS,
|
ATTR_BRIGHTNESS,
|
||||||
ATTR_COLOR_TEMP,
|
ATTR_COLOR_TEMP,
|
||||||
|
ATTR_FLASH,
|
||||||
ATTR_TRANSITION,
|
ATTR_TRANSITION,
|
||||||
ATTR_XY_COLOR,
|
ATTR_XY_COLOR,
|
||||||
COLOR_MODE_BRIGHTNESS,
|
COLOR_MODE_BRIGHTNESS,
|
||||||
COLOR_MODE_COLOR_TEMP,
|
COLOR_MODE_COLOR_TEMP,
|
||||||
COLOR_MODE_ONOFF,
|
COLOR_MODE_ONOFF,
|
||||||
COLOR_MODE_XY,
|
COLOR_MODE_XY,
|
||||||
|
SUPPORT_FLASH,
|
||||||
SUPPORT_TRANSITION,
|
SUPPORT_TRANSITION,
|
||||||
LightEntity,
|
LightEntity,
|
||||||
)
|
)
|
||||||
@ -32,6 +35,7 @@ ALLOWED_ERRORS = [
|
|||||||
'device (groupedLight) is "soft off", command (on) may not have effect',
|
'device (groupedLight) is "soft off", command (on) may not have effect',
|
||||||
"device (light) has communication issues, command (on) may not have effect",
|
"device (light) has communication issues, command (on) may not have effect",
|
||||||
'device (light) is "soft off", command (on) may not have effect',
|
'device (light) is "soft off", command (on) may not have effect',
|
||||||
|
"attribute (supportedAlertActions) cannot be written",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -88,6 +92,7 @@ class GroupedHueLight(HueBaseEntity, LightEntity):
|
|||||||
self.group = group
|
self.group = group
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.api: HueBridgeV2 = bridge.api
|
self.api: HueBridgeV2 = bridge.api
|
||||||
|
self._attr_supported_features |= SUPPORT_FLASH
|
||||||
self._attr_supported_features |= SUPPORT_TRANSITION
|
self._attr_supported_features |= SUPPORT_TRANSITION
|
||||||
|
|
||||||
# Entities for Hue groups are disabled by default
|
# Entities for Hue groups are disabled by default
|
||||||
@ -146,6 +151,7 @@ class GroupedHueLight(HueBaseEntity, LightEntity):
|
|||||||
xy_color = kwargs.get(ATTR_XY_COLOR)
|
xy_color = kwargs.get(ATTR_XY_COLOR)
|
||||||
color_temp = kwargs.get(ATTR_COLOR_TEMP)
|
color_temp = kwargs.get(ATTR_COLOR_TEMP)
|
||||||
brightness = kwargs.get(ATTR_BRIGHTNESS)
|
brightness = kwargs.get(ATTR_BRIGHTNESS)
|
||||||
|
flash = kwargs.get(ATTR_FLASH)
|
||||||
if brightness is not None:
|
if brightness is not None:
|
||||||
# Hue uses a range of [0, 100] to control brightness.
|
# Hue uses a range of [0, 100] to control brightness.
|
||||||
brightness = float((brightness / 255) * 100)
|
brightness = float((brightness / 255) * 100)
|
||||||
@ -160,6 +166,7 @@ class GroupedHueLight(HueBaseEntity, LightEntity):
|
|||||||
and xy_color is None
|
and xy_color is None
|
||||||
and color_temp is None
|
and color_temp is None
|
||||||
and transition is None
|
and transition is None
|
||||||
|
and flash is None
|
||||||
):
|
):
|
||||||
await self.bridge.async_request_call(
|
await self.bridge.async_request_call(
|
||||||
self.controller.set_state,
|
self.controller.set_state,
|
||||||
@ -180,6 +187,7 @@ class GroupedHueLight(HueBaseEntity, LightEntity):
|
|||||||
color_xy=xy_color if light.supports_color else None,
|
color_xy=xy_color if light.supports_color else None,
|
||||||
color_temp=color_temp if light.supports_color_temperature else None,
|
color_temp=color_temp if light.supports_color_temperature else None,
|
||||||
transition_time=transition,
|
transition_time=transition,
|
||||||
|
alert=AlertEffectType.BREATHE if flash is not None else None,
|
||||||
allowed_errors=ALLOWED_ERRORS,
|
allowed_errors=ALLOWED_ERRORS,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -6,17 +6,20 @@ from typing import Any
|
|||||||
from aiohue import HueBridgeV2
|
from aiohue import HueBridgeV2
|
||||||
from aiohue.v2.controllers.events import EventType
|
from aiohue.v2.controllers.events import EventType
|
||||||
from aiohue.v2.controllers.lights import LightsController
|
from aiohue.v2.controllers.lights import LightsController
|
||||||
|
from aiohue.v2.models.feature import AlertEffectType
|
||||||
from aiohue.v2.models.light import Light
|
from aiohue.v2.models.light import Light
|
||||||
|
|
||||||
from homeassistant.components.light import (
|
from homeassistant.components.light import (
|
||||||
ATTR_BRIGHTNESS,
|
ATTR_BRIGHTNESS,
|
||||||
ATTR_COLOR_TEMP,
|
ATTR_COLOR_TEMP,
|
||||||
|
ATTR_FLASH,
|
||||||
ATTR_TRANSITION,
|
ATTR_TRANSITION,
|
||||||
ATTR_XY_COLOR,
|
ATTR_XY_COLOR,
|
||||||
COLOR_MODE_BRIGHTNESS,
|
COLOR_MODE_BRIGHTNESS,
|
||||||
COLOR_MODE_COLOR_TEMP,
|
COLOR_MODE_COLOR_TEMP,
|
||||||
COLOR_MODE_ONOFF,
|
COLOR_MODE_ONOFF,
|
||||||
COLOR_MODE_XY,
|
COLOR_MODE_XY,
|
||||||
|
SUPPORT_FLASH,
|
||||||
SUPPORT_TRANSITION,
|
SUPPORT_TRANSITION,
|
||||||
LightEntity,
|
LightEntity,
|
||||||
)
|
)
|
||||||
@ -31,6 +34,7 @@ from .entity import HueBaseEntity
|
|||||||
ALLOWED_ERRORS = [
|
ALLOWED_ERRORS = [
|
||||||
"device (light) has communication issues, command (on) may not have effect",
|
"device (light) has communication issues, command (on) may not have effect",
|
||||||
'device (light) is "soft off", command (on) may not have effect',
|
'device (light) is "soft off", command (on) may not have effect',
|
||||||
|
"attribute (supportedAlertActions) cannot be written",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -68,6 +72,7 @@ class HueLight(HueBaseEntity, LightEntity):
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the light."""
|
"""Initialize the light."""
|
||||||
super().__init__(bridge, controller, resource)
|
super().__init__(bridge, controller, resource)
|
||||||
|
self._attr_supported_features |= SUPPORT_FLASH
|
||||||
self.resource = resource
|
self.resource = resource
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self._supported_color_modes = set()
|
self._supported_color_modes = set()
|
||||||
@ -154,6 +159,7 @@ class HueLight(HueBaseEntity, LightEntity):
|
|||||||
xy_color = kwargs.get(ATTR_XY_COLOR)
|
xy_color = kwargs.get(ATTR_XY_COLOR)
|
||||||
color_temp = kwargs.get(ATTR_COLOR_TEMP)
|
color_temp = kwargs.get(ATTR_COLOR_TEMP)
|
||||||
brightness = kwargs.get(ATTR_BRIGHTNESS)
|
brightness = kwargs.get(ATTR_BRIGHTNESS)
|
||||||
|
flash = kwargs.get(ATTR_FLASH)
|
||||||
if brightness is not None:
|
if brightness is not None:
|
||||||
# Hue uses a range of [0, 100] to control brightness.
|
# Hue uses a range of [0, 100] to control brightness.
|
||||||
brightness = float((brightness / 255) * 100)
|
brightness = float((brightness / 255) * 100)
|
||||||
@ -169,12 +175,14 @@ class HueLight(HueBaseEntity, LightEntity):
|
|||||||
color_xy=xy_color,
|
color_xy=xy_color,
|
||||||
color_temp=color_temp,
|
color_temp=color_temp,
|
||||||
transition_time=transition,
|
transition_time=transition,
|
||||||
|
alert=AlertEffectType.BREATHE if flash is not None else None,
|
||||||
allowed_errors=ALLOWED_ERRORS,
|
allowed_errors=ALLOWED_ERRORS,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||||
"""Turn the light off."""
|
"""Turn the light off."""
|
||||||
transition = kwargs.get(ATTR_TRANSITION)
|
transition = kwargs.get(ATTR_TRANSITION)
|
||||||
|
flash = kwargs.get(ATTR_FLASH)
|
||||||
if transition is not None:
|
if transition is not None:
|
||||||
# hue transition duration is in milliseconds
|
# hue transition duration is in milliseconds
|
||||||
transition = int(transition * 1000)
|
transition = int(transition * 1000)
|
||||||
@ -183,5 +191,6 @@ class HueLight(HueBaseEntity, LightEntity):
|
|||||||
id=self.resource.id,
|
id=self.resource.id,
|
||||||
on=False,
|
on=False,
|
||||||
transition_time=transition,
|
transition_time=transition,
|
||||||
|
alert=AlertEffectType.BREATHE if flash is not None else None,
|
||||||
allowed_errors=ALLOWED_ERRORS,
|
allowed_errors=ALLOWED_ERRORS,
|
||||||
)
|
)
|
||||||
|
@ -121,6 +121,17 @@ async def test_light_turn_on_service(hass, mock_bridge_v2, v2_resources_test_dat
|
|||||||
assert mock_bridge_v2.mock_requests[1]["json"]["on"]["on"] is True
|
assert mock_bridge_v2.mock_requests[1]["json"]["on"]["on"] is True
|
||||||
assert mock_bridge_v2.mock_requests[1]["json"]["dynamics"]["duration"] == 6000
|
assert mock_bridge_v2.mock_requests[1]["json"]["dynamics"]["duration"] == 6000
|
||||||
|
|
||||||
|
# test again with sending flash/alert
|
||||||
|
await hass.services.async_call(
|
||||||
|
"light",
|
||||||
|
"turn_on",
|
||||||
|
{"entity_id": test_light_id, "flash": "long"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert len(mock_bridge_v2.mock_requests) == 3
|
||||||
|
assert mock_bridge_v2.mock_requests[2]["json"]["on"]["on"] is True
|
||||||
|
assert mock_bridge_v2.mock_requests[2]["json"]["alert"]["action"] == "breathe"
|
||||||
|
|
||||||
|
|
||||||
async def test_light_turn_off_service(hass, mock_bridge_v2, v2_resources_test_data):
|
async def test_light_turn_off_service(hass, mock_bridge_v2, v2_resources_test_data):
|
||||||
"""Test calling the turn off service on a light."""
|
"""Test calling the turn off service on a light."""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user