Fix Flash effect for Hue lights (#61733)

This commit is contained in:
Marcel van der Veldt 2021-12-14 01:27:58 +01:00 committed by GitHub
parent 89a6640b82
commit 438d19f72b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 0 deletions

View File

@ -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,
) )

View File

@ -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,
) )

View File

@ -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."""