mirror of
https://github.com/home-assistant/core.git
synced 2025-07-17 02:07:09 +00:00
Add support for RGBW color to blebox light (#49562)
This commit is contained in:
parent
51c8b1eb0b
commit
2583e4bdc9
@ -5,19 +5,13 @@ from blebox_uniapi.error import BadOnValueError
|
|||||||
|
|
||||||
from homeassistant.components.light import (
|
from homeassistant.components.light import (
|
||||||
ATTR_BRIGHTNESS,
|
ATTR_BRIGHTNESS,
|
||||||
ATTR_HS_COLOR,
|
ATTR_RGBW_COLOR,
|
||||||
ATTR_WHITE_VALUE,
|
COLOR_MODE_BRIGHTNESS,
|
||||||
SUPPORT_BRIGHTNESS,
|
COLOR_MODE_ONOFF,
|
||||||
SUPPORT_COLOR,
|
COLOR_MODE_RGBW,
|
||||||
SUPPORT_WHITE_VALUE,
|
|
||||||
LightEntity,
|
LightEntity,
|
||||||
)
|
)
|
||||||
from homeassistant.util.color import (
|
from homeassistant.util.color import color_rgb_to_hex, rgb_hex_to_rgb_list
|
||||||
color_hs_to_RGB,
|
|
||||||
color_rgb_to_hex,
|
|
||||||
color_RGB_to_hs,
|
|
||||||
rgb_hex_to_rgb_list,
|
|
||||||
)
|
|
||||||
|
|
||||||
from . import BleBoxEntity, create_blebox_entities
|
from . import BleBoxEntity, create_blebox_entities
|
||||||
|
|
||||||
@ -36,12 +30,9 @@ class BleBoxLightEntity(BleBoxEntity, LightEntity):
|
|||||||
"""Representation of BleBox lights."""
|
"""Representation of BleBox lights."""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def supported_features(self):
|
def supported_color_modes(self):
|
||||||
"""Return supported features."""
|
"""Return supported color modes."""
|
||||||
white = SUPPORT_WHITE_VALUE if self._feature.supports_white else 0
|
return {self.color_mode}
|
||||||
color = SUPPORT_COLOR if self._feature.supports_color else 0
|
|
||||||
brightness = SUPPORT_BRIGHTNESS if self._feature.supports_brightness else 0
|
|
||||||
return white | color | brightness
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self):
|
def is_on(self):
|
||||||
@ -54,25 +45,27 @@ class BleBoxLightEntity(BleBoxEntity, LightEntity):
|
|||||||
return self._feature.brightness
|
return self._feature.brightness
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def white_value(self):
|
def color_mode(self):
|
||||||
"""Return the white value."""
|
"""Return the color mode."""
|
||||||
return self._feature.white_value
|
if self._feature.supports_white and self._feature.supports_color:
|
||||||
|
return COLOR_MODE_RGBW
|
||||||
|
if self._feature.supports_brightness:
|
||||||
|
return COLOR_MODE_BRIGHTNESS
|
||||||
|
return COLOR_MODE_ONOFF
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hs_color(self):
|
def rgbw_color(self):
|
||||||
"""Return the hue and saturation."""
|
"""Return the hue and saturation."""
|
||||||
rgbw_hex = self._feature.rgbw_hex
|
rgbw_hex = self._feature.rgbw_hex
|
||||||
if rgbw_hex is None:
|
if rgbw_hex is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
rgb = rgb_hex_to_rgb_list(rgbw_hex)[0:3]
|
return tuple(rgb_hex_to_rgb_list(rgbw_hex)[0:4])
|
||||||
return color_RGB_to_hs(*rgb)
|
|
||||||
|
|
||||||
async def async_turn_on(self, **kwargs):
|
async def async_turn_on(self, **kwargs):
|
||||||
"""Turn the light on."""
|
"""Turn the light on."""
|
||||||
|
|
||||||
white = kwargs.get(ATTR_WHITE_VALUE)
|
rgbw = kwargs.get(ATTR_RGBW_COLOR)
|
||||||
hs_color = kwargs.get(ATTR_HS_COLOR)
|
|
||||||
brightness = kwargs.get(ATTR_BRIGHTNESS)
|
brightness = kwargs.get(ATTR_BRIGHTNESS)
|
||||||
|
|
||||||
feature = self._feature
|
feature = self._feature
|
||||||
@ -81,12 +74,9 @@ class BleBoxLightEntity(BleBoxEntity, LightEntity):
|
|||||||
if brightness is not None:
|
if brightness is not None:
|
||||||
value = feature.apply_brightness(value, brightness)
|
value = feature.apply_brightness(value, brightness)
|
||||||
|
|
||||||
if white is not None:
|
if rgbw is not None:
|
||||||
value = feature.apply_white(value, white)
|
value = feature.apply_white(value, rgbw[3])
|
||||||
|
value = feature.apply_color(value, color_rgb_to_hex(*rgbw[0:3]))
|
||||||
if hs_color is not None:
|
|
||||||
raw_rgb = color_rgb_to_hex(*color_hs_to_RGB(*hs_color))
|
|
||||||
value = feature.apply_color(value, raw_rgb)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await self._feature.async_on(value)
|
await self._feature.async_on(value)
|
||||||
|
@ -7,21 +7,13 @@ import pytest
|
|||||||
|
|
||||||
from homeassistant.components.light import (
|
from homeassistant.components.light import (
|
||||||
ATTR_BRIGHTNESS,
|
ATTR_BRIGHTNESS,
|
||||||
ATTR_HS_COLOR,
|
ATTR_RGBW_COLOR,
|
||||||
ATTR_WHITE_VALUE,
|
ATTR_SUPPORTED_COLOR_MODES,
|
||||||
SUPPORT_BRIGHTNESS,
|
COLOR_MODE_BRIGHTNESS,
|
||||||
SUPPORT_COLOR,
|
COLOR_MODE_RGBW,
|
||||||
SUPPORT_WHITE_VALUE,
|
|
||||||
)
|
|
||||||
from homeassistant.const import (
|
|
||||||
ATTR_SUPPORTED_FEATURES,
|
|
||||||
SERVICE_TURN_OFF,
|
|
||||||
SERVICE_TURN_ON,
|
|
||||||
STATE_OFF,
|
|
||||||
STATE_ON,
|
|
||||||
)
|
)
|
||||||
|
from homeassistant.const import SERVICE_TURN_OFF, SERVICE_TURN_ON, STATE_OFF, STATE_ON
|
||||||
from homeassistant.helpers import device_registry as dr
|
from homeassistant.helpers import device_registry as dr
|
||||||
from homeassistant.util import color
|
|
||||||
|
|
||||||
from .conftest import async_setup_entity, mock_feature
|
from .conftest import async_setup_entity, mock_feature
|
||||||
|
|
||||||
@ -59,8 +51,8 @@ async def test_dimmer_init(dimmer, hass, config):
|
|||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state.name == "dimmerBox-brightness"
|
assert state.name == "dimmerBox-brightness"
|
||||||
|
|
||||||
supported_features = state.attributes[ATTR_SUPPORTED_FEATURES]
|
color_modes = state.attributes[ATTR_SUPPORTED_COLOR_MODES]
|
||||||
assert supported_features & SUPPORT_BRIGHTNESS
|
assert color_modes == [COLOR_MODE_BRIGHTNESS]
|
||||||
|
|
||||||
assert state.attributes[ATTR_BRIGHTNESS] == 65
|
assert state.attributes[ATTR_BRIGHTNESS] == 65
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
@ -230,8 +222,8 @@ async def test_wlightbox_s_init(wlightbox_s, hass, config):
|
|||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state.name == "wLightBoxS-color"
|
assert state.name == "wLightBoxS-color"
|
||||||
|
|
||||||
supported_features = state.attributes[ATTR_SUPPORTED_FEATURES]
|
color_modes = state.attributes[ATTR_SUPPORTED_COLOR_MODES]
|
||||||
assert supported_features & SUPPORT_BRIGHTNESS
|
assert color_modes == [COLOR_MODE_BRIGHTNESS]
|
||||||
|
|
||||||
assert ATTR_BRIGHTNESS not in state.attributes
|
assert ATTR_BRIGHTNESS not in state.attributes
|
||||||
assert state.state == STATE_OFF
|
assert state.state == STATE_OFF
|
||||||
@ -330,13 +322,11 @@ async def test_wlightbox_init(wlightbox, hass, config):
|
|||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state.name == "wLightBox-color"
|
assert state.name == "wLightBox-color"
|
||||||
|
|
||||||
supported_features = state.attributes[ATTR_SUPPORTED_FEATURES]
|
color_modes = state.attributes[ATTR_SUPPORTED_COLOR_MODES]
|
||||||
assert supported_features & SUPPORT_WHITE_VALUE
|
assert color_modes == [COLOR_MODE_RGBW]
|
||||||
assert supported_features & SUPPORT_COLOR
|
|
||||||
|
|
||||||
assert ATTR_WHITE_VALUE not in state.attributes
|
|
||||||
assert ATTR_HS_COLOR not in state.attributes
|
|
||||||
assert ATTR_BRIGHTNESS not in state.attributes
|
assert ATTR_BRIGHTNESS not in state.attributes
|
||||||
|
assert ATTR_RGBW_COLOR not in state.attributes
|
||||||
assert state.state == STATE_OFF
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
device_registry = dr.async_get(hass)
|
device_registry = dr.async_get(hass)
|
||||||
@ -363,12 +353,11 @@ async def test_wlightbox_update(wlightbox, hass, config):
|
|||||||
await async_setup_entity(hass, config, entity_id)
|
await async_setup_entity(hass, config, entity_id)
|
||||||
|
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state.attributes[ATTR_HS_COLOR] == (352.32, 100.0)
|
assert state.attributes[ATTR_RGBW_COLOR] == (0xFA, 0x00, 0x20, 0x3A)
|
||||||
assert state.attributes[ATTR_WHITE_VALUE] == 0x3A
|
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
|
||||||
async def test_wlightbox_on_via_just_whiteness(wlightbox, hass, config):
|
async def test_wlightbox_on_rgbw(wlightbox, hass, config):
|
||||||
"""Test light on."""
|
"""Test light on."""
|
||||||
|
|
||||||
feature_mock, entity_id = wlightbox
|
feature_mock, entity_id = wlightbox
|
||||||
@ -385,125 +374,37 @@ async def test_wlightbox_on_via_just_whiteness(wlightbox, hass, config):
|
|||||||
|
|
||||||
def turn_on(value):
|
def turn_on(value):
|
||||||
feature_mock.is_on = True
|
feature_mock.is_on = True
|
||||||
assert value == "f1e2d3c7"
|
assert value == "c1d2f3c7"
|
||||||
feature_mock.white_value = 0xC7 # on
|
feature_mock.white_value = 0xC7 # on
|
||||||
feature_mock.rgbw_hex = "f1e2d3c7"
|
feature_mock.rgbw_hex = "c1d2f3c7"
|
||||||
|
|
||||||
feature_mock.async_on = AsyncMock(side_effect=turn_on)
|
feature_mock.async_on = AsyncMock(side_effect=turn_on)
|
||||||
|
|
||||||
def apply_white(value, white):
|
def apply_white(value, white):
|
||||||
assert value == "f1e2d305"
|
assert value == "00010203"
|
||||||
assert white == 0xC7
|
assert white == 0xC7
|
||||||
return "f1e2d3c7"
|
return "000102c7"
|
||||||
|
|
||||||
feature_mock.apply_white = apply_white
|
feature_mock.apply_white = apply_white
|
||||||
|
|
||||||
feature_mock.sensible_on_value = "f1e2d305"
|
|
||||||
|
|
||||||
await hass.services.async_call(
|
|
||||||
"light",
|
|
||||||
SERVICE_TURN_ON,
|
|
||||||
{"entity_id": entity_id, ATTR_WHITE_VALUE: 0xC7},
|
|
||||||
blocking=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
state = hass.states.get(entity_id)
|
|
||||||
assert state.state == STATE_ON
|
|
||||||
assert state.attributes[ATTR_WHITE_VALUE] == 0xC7
|
|
||||||
|
|
||||||
assert state.attributes[ATTR_HS_COLOR] == color.color_RGB_to_hs(0xF1, 0xE2, 0xD3)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_wlightbox_on_via_reset_whiteness(wlightbox, hass, config):
|
|
||||||
"""Test light on."""
|
|
||||||
|
|
||||||
feature_mock, entity_id = wlightbox
|
|
||||||
|
|
||||||
def initial_update():
|
|
||||||
feature_mock.is_on = False
|
|
||||||
|
|
||||||
feature_mock.async_update = AsyncMock(side_effect=initial_update)
|
|
||||||
await async_setup_entity(hass, config, entity_id)
|
|
||||||
feature_mock.async_update = AsyncMock()
|
|
||||||
|
|
||||||
state = hass.states.get(entity_id)
|
|
||||||
assert state.state == STATE_OFF
|
|
||||||
|
|
||||||
def turn_on(value):
|
|
||||||
feature_mock.is_on = True
|
|
||||||
feature_mock.white_value = 0x0
|
|
||||||
assert value == "f1e2d300"
|
|
||||||
feature_mock.rgbw_hex = "f1e2d300"
|
|
||||||
|
|
||||||
feature_mock.async_on = AsyncMock(side_effect=turn_on)
|
|
||||||
|
|
||||||
def apply_white(value, white):
|
|
||||||
assert value == "f1e2d305"
|
|
||||||
assert white == 0x0
|
|
||||||
return "f1e2d300"
|
|
||||||
|
|
||||||
feature_mock.apply_white = apply_white
|
|
||||||
|
|
||||||
feature_mock.sensible_on_value = "f1e2d305"
|
|
||||||
|
|
||||||
await hass.services.async_call(
|
|
||||||
"light",
|
|
||||||
SERVICE_TURN_ON,
|
|
||||||
{"entity_id": entity_id, ATTR_WHITE_VALUE: 0x0},
|
|
||||||
blocking=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
state = hass.states.get(entity_id)
|
|
||||||
assert state.state == STATE_ON
|
|
||||||
assert state.attributes[ATTR_WHITE_VALUE] == 0x0
|
|
||||||
assert state.attributes[ATTR_HS_COLOR] == color.color_RGB_to_hs(0xF1, 0xE2, 0xD3)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_wlightbox_on_via_just_hsl_color(wlightbox, hass, config):
|
|
||||||
"""Test light on."""
|
|
||||||
|
|
||||||
feature_mock, entity_id = wlightbox
|
|
||||||
|
|
||||||
def initial_update():
|
|
||||||
feature_mock.is_on = False
|
|
||||||
feature_mock.rgbw_hex = "00000000"
|
|
||||||
|
|
||||||
feature_mock.async_update = AsyncMock(side_effect=initial_update)
|
|
||||||
await async_setup_entity(hass, config, entity_id)
|
|
||||||
feature_mock.async_update = AsyncMock()
|
|
||||||
|
|
||||||
state = hass.states.get(entity_id)
|
|
||||||
assert state.state == STATE_OFF
|
|
||||||
|
|
||||||
hs_color = color.color_RGB_to_hs(0xFF, 0xA1, 0xB2)
|
|
||||||
|
|
||||||
def turn_on(value):
|
|
||||||
feature_mock.is_on = True
|
|
||||||
assert value == "ffa1b2e4"
|
|
||||||
feature_mock.white_value = 0xE4
|
|
||||||
feature_mock.rgbw_hex = value
|
|
||||||
|
|
||||||
feature_mock.async_on = AsyncMock(side_effect=turn_on)
|
|
||||||
|
|
||||||
def apply_color(value, color_value):
|
def apply_color(value, color_value):
|
||||||
assert value == "c1a2e3e4"
|
assert value == "000102c7"
|
||||||
assert color_value == "ffa0b1"
|
assert color_value == "c1d2f3"
|
||||||
return "ffa1b2e4"
|
return "c1d2f3c7"
|
||||||
|
|
||||||
feature_mock.apply_color = apply_color
|
feature_mock.apply_color = apply_color
|
||||||
feature_mock.sensible_on_value = "c1a2e3e4"
|
feature_mock.sensible_on_value = "00010203"
|
||||||
|
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
"light",
|
"light",
|
||||||
SERVICE_TURN_ON,
|
SERVICE_TURN_ON,
|
||||||
{"entity_id": entity_id, ATTR_HS_COLOR: hs_color},
|
{"entity_id": entity_id, ATTR_RGBW_COLOR: (0xC1, 0xD2, 0xF3, 0xC7)},
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state.attributes[ATTR_HS_COLOR] == hs_color
|
|
||||||
assert state.attributes[ATTR_WHITE_VALUE] == 0xE4
|
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
|
assert state.attributes[ATTR_RGBW_COLOR] == (0xC1, 0xD2, 0xF3, 0xC7)
|
||||||
|
|
||||||
|
|
||||||
async def test_wlightbox_on_to_last_color(wlightbox, hass, config):
|
async def test_wlightbox_on_to_last_color(wlightbox, hass, config):
|
||||||
@ -538,8 +439,7 @@ async def test_wlightbox_on_to_last_color(wlightbox, hass, config):
|
|||||||
)
|
)
|
||||||
|
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state.attributes[ATTR_WHITE_VALUE] == 0xE4
|
assert state.attributes[ATTR_RGBW_COLOR] == (0xF1, 0xE2, 0xD3, 0xE4)
|
||||||
assert state.attributes[ATTR_HS_COLOR] == color.color_RGB_to_hs(0xF1, 0xE2, 0xD3)
|
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
|
||||||
@ -573,8 +473,7 @@ async def test_wlightbox_off(wlightbox, hass, config):
|
|||||||
)
|
)
|
||||||
|
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert ATTR_WHITE_VALUE not in state.attributes
|
assert ATTR_RGBW_COLOR not in state.attributes
|
||||||
assert ATTR_HS_COLOR not in state.attributes
|
|
||||||
assert state.state == STATE_OFF
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user