Improve WLED white value support for RGBW strips (#29312)
This commit is contained in:
parent
8f608608ed
commit
76aaf8b560
2 changed files with 51 additions and 9 deletions
|
@ -10,11 +10,13 @@ from homeassistant.components.light import (
|
||||||
ATTR_EFFECT,
|
ATTR_EFFECT,
|
||||||
ATTR_HS_COLOR,
|
ATTR_HS_COLOR,
|
||||||
ATTR_TRANSITION,
|
ATTR_TRANSITION,
|
||||||
|
ATTR_WHITE_VALUE,
|
||||||
SUPPORT_BRIGHTNESS,
|
SUPPORT_BRIGHTNESS,
|
||||||
SUPPORT_COLOR,
|
SUPPORT_COLOR,
|
||||||
SUPPORT_COLOR_TEMP,
|
SUPPORT_COLOR_TEMP,
|
||||||
SUPPORT_EFFECT,
|
SUPPORT_EFFECT,
|
||||||
SUPPORT_TRANSITION,
|
SUPPORT_TRANSITION,
|
||||||
|
SUPPORT_WHITE_VALUE,
|
||||||
Light,
|
Light,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
@ -79,6 +81,7 @@ class WLEDLight(Light, WLEDDeviceEntity):
|
||||||
self._color: Optional[Tuple[float, float]] = None
|
self._color: Optional[Tuple[float, float]] = None
|
||||||
self._effect: Optional[str] = None
|
self._effect: Optional[str] = None
|
||||||
self._state: Optional[bool] = None
|
self._state: Optional[bool] = None
|
||||||
|
self._white_value: Optional[int] = None
|
||||||
|
|
||||||
# Only apply the segment ID if it is not the first segment
|
# Only apply the segment ID if it is not the first segment
|
||||||
name = wled.device.info.name
|
name = wled.device.info.name
|
||||||
|
@ -107,10 +110,15 @@ class WLEDLight(Light, WLEDDeviceEntity):
|
||||||
"""Return the brightness of this light between 1..255."""
|
"""Return the brightness of this light between 1..255."""
|
||||||
return self._brightness
|
return self._brightness
|
||||||
|
|
||||||
|
@property
|
||||||
|
def white_value(self) -> Optional[int]:
|
||||||
|
"""Return the white value of this light between 0..255."""
|
||||||
|
return self._white_value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def supported_features(self) -> int:
|
def supported_features(self) -> int:
|
||||||
"""Flag supported features."""
|
"""Flag supported features."""
|
||||||
return (
|
flags = (
|
||||||
SUPPORT_BRIGHTNESS
|
SUPPORT_BRIGHTNESS
|
||||||
| SUPPORT_COLOR
|
| SUPPORT_COLOR
|
||||||
| SUPPORT_COLOR_TEMP
|
| SUPPORT_COLOR_TEMP
|
||||||
|
@ -118,6 +126,11 @@ class WLEDLight(Light, WLEDDeviceEntity):
|
||||||
| SUPPORT_TRANSITION
|
| SUPPORT_TRANSITION
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if self._rgbw:
|
||||||
|
flags |= SUPPORT_WHITE_VALUE
|
||||||
|
|
||||||
|
return flags
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def effect_list(self) -> List[str]:
|
def effect_list(self) -> List[str]:
|
||||||
"""Return the list of supported effects."""
|
"""Return the list of supported effects."""
|
||||||
|
@ -163,11 +176,21 @@ class WLEDLight(Light, WLEDDeviceEntity):
|
||||||
if ATTR_EFFECT in kwargs:
|
if ATTR_EFFECT in kwargs:
|
||||||
data[ATTR_EFFECT] = kwargs[ATTR_EFFECT]
|
data[ATTR_EFFECT] = kwargs[ATTR_EFFECT]
|
||||||
|
|
||||||
# Support for RGBW strips
|
# Support for RGBW strips, adds white value
|
||||||
if self._rgbw and any(x in (ATTR_COLOR_TEMP, ATTR_HS_COLOR) for x in kwargs):
|
if self._rgbw and any(
|
||||||
data[ATTR_COLOR_PRIMARY] = color_util.color_rgb_to_rgbw(
|
x in (ATTR_COLOR_TEMP, ATTR_HS_COLOR, ATTR_WHITE_VALUE) for x in kwargs
|
||||||
*data[ATTR_COLOR_PRIMARY]
|
):
|
||||||
)
|
# WLED cannot just accept a white value, it needs the color.
|
||||||
|
# We use the last know color in case just the white value changes.
|
||||||
|
if not any(x in (ATTR_COLOR_TEMP, ATTR_HS_COLOR) for x in kwargs):
|
||||||
|
hue, sat = self._color
|
||||||
|
data[ATTR_COLOR_PRIMARY] = color_util.color_hsv_to_RGB(hue, sat, 100)
|
||||||
|
|
||||||
|
# Add requested or last known white value
|
||||||
|
if ATTR_WHITE_VALUE in kwargs:
|
||||||
|
data[ATTR_COLOR_PRIMARY] += (kwargs[ATTR_WHITE_VALUE],)
|
||||||
|
else:
|
||||||
|
data[ATTR_COLOR_PRIMARY] += (self._white_value,)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await self.wled.light(**data)
|
await self.wled.light(**data)
|
||||||
|
@ -186,6 +209,9 @@ class WLEDLight(Light, WLEDDeviceEntity):
|
||||||
if ATTR_COLOR_TEMP in kwargs:
|
if ATTR_COLOR_TEMP in kwargs:
|
||||||
self._color = color_util.color_temperature_to_hs(mireds)
|
self._color = color_util.color_temperature_to_hs(mireds)
|
||||||
|
|
||||||
|
if ATTR_WHITE_VALUE in kwargs:
|
||||||
|
self._white_value = kwargs[ATTR_WHITE_VALUE]
|
||||||
|
|
||||||
except WLEDError:
|
except WLEDError:
|
||||||
_LOGGER.error("An error occurred while turning on WLED light.")
|
_LOGGER.error("An error occurred while turning on WLED light.")
|
||||||
self._available = False
|
self._available = False
|
||||||
|
@ -198,9 +224,9 @@ class WLEDLight(Light, WLEDDeviceEntity):
|
||||||
self._state = self.wled.device.state.on
|
self._state = self.wled.device.state.on
|
||||||
|
|
||||||
color = self.wled.device.state.segments[self._segment].color_primary
|
color = self.wled.device.state.segments[self._segment].color_primary
|
||||||
|
self._color = color_util.color_RGB_to_hs(*color[:3])
|
||||||
if self._rgbw:
|
if self._rgbw:
|
||||||
color = color_util.color_rgbw_to_rgb(*color)
|
self._white_value = color[-1]
|
||||||
self._color = color_util.color_RGB_to_hs(*color)
|
|
||||||
|
|
||||||
playlist = self.wled.device.state.playlist
|
playlist = self.wled.device.state.playlist
|
||||||
if playlist == -1:
|
if playlist == -1:
|
||||||
|
|
|
@ -8,6 +8,7 @@ from homeassistant.components.light import (
|
||||||
ATTR_HS_COLOR,
|
ATTR_HS_COLOR,
|
||||||
ATTR_RGB_COLOR,
|
ATTR_RGB_COLOR,
|
||||||
ATTR_TRANSITION,
|
ATTR_TRANSITION,
|
||||||
|
ATTR_WHITE_VALUE,
|
||||||
DOMAIN as LIGHT_DOMAIN,
|
DOMAIN as LIGHT_DOMAIN,
|
||||||
)
|
)
|
||||||
from homeassistant.components.wled.const import (
|
from homeassistant.components.wled.const import (
|
||||||
|
@ -164,7 +165,8 @@ async def test_rgbw_light(
|
||||||
|
|
||||||
state = hass.states.get("light.wled_rgbw_light")
|
state = hass.states.get("light.wled_rgbw_light")
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
assert state.attributes.get(ATTR_HS_COLOR) == (0.0, 64.706)
|
assert state.attributes.get(ATTR_HS_COLOR) == (0.0, 100.0)
|
||||||
|
assert state.attributes.get(ATTR_WHITE_VALUE) == 139
|
||||||
|
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
LIGHT_DOMAIN,
|
LIGHT_DOMAIN,
|
||||||
|
@ -177,3 +179,17 @@ async def test_rgbw_light(
|
||||||
state = hass.states.get("light.wled_rgbw_light")
|
state = hass.states.get("light.wled_rgbw_light")
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
assert state.attributes.get(ATTR_HS_COLOR) == (28.874, 72.522)
|
assert state.attributes.get(ATTR_HS_COLOR) == (28.874, 72.522)
|
||||||
|
assert state.attributes.get(ATTR_WHITE_VALUE) == 139
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
LIGHT_DOMAIN,
|
||||||
|
SERVICE_TURN_ON,
|
||||||
|
{ATTR_ENTITY_ID: "light.wled_rgbw_light", ATTR_WHITE_VALUE: 100},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("light.wled_rgbw_light")
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
assert state.attributes.get(ATTR_HS_COLOR) == (28.874, 72.522)
|
||||||
|
assert state.attributes.get(ATTR_WHITE_VALUE) == 100
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue