Skip to content

Commit

Permalink
- Fix color temp being inaccurate for low brightness RGBWW lights
Browse files Browse the repository at this point in the history
- Swap `t` and `T` that was inverted by mistake
- Support HS color mode
  • Loading branch information
Breina committed Aug 2, 2023
1 parent 72bc071 commit bc35ee8
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 14 deletions.
52 changes: 41 additions & 11 deletions custom_components/artnet_led/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
SUPPORT_TRANSITION,
PLATFORM_SCHEMA,
LightEntity, COLOR_MODE_ONOFF, COLOR_MODE_WHITE, ATTR_WHITE, ATTR_COLOR_TEMP_KELVIN, SUPPORT_FLASH, ATTR_FLASH,
FLASH_SHORT, FLASH_LONG)
FLASH_SHORT, FLASH_LONG, COLOR_MODE_HS, ATTR_HS_COLOR)
from homeassistant.const import CONF_DEVICES, STATE_OFF, STATE_ON
from homeassistant.const import CONF_FRIENDLY_NAME as CONF_DEVICE_FRIENDLY_NAME
from homeassistant.const import CONF_HOST as CONF_NODE_HOST
Expand Down Expand Up @@ -666,6 +666,7 @@ class DmxRGB(DmxBaseLight):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self._supported_color_modes.add(COLOR_MODE_RGB)
self._supported_color_modes.add(COLOR_MODE_HS)
self._features = SUPPORT_TRANSITION | SUPPORT_FLASH
self._color_mode = COLOR_MODE_RGB
self._vals = (255, 255, 255)
Expand Down Expand Up @@ -716,6 +717,10 @@ async def async_turn_on(self, **kwargs):
if ATTR_RGB_COLOR in kwargs:
self._vals = kwargs[ATTR_RGB_COLOR]

if ATTR_HS_COLOR in kwargs:
hue, sat = kwargs[ATTR_HS_COLOR]
self._vals = color_util.color_hs_to_RGB(hue, sat)

if ATTR_BRIGHTNESS in kwargs:
self._attr_brightness = kwargs[ATTR_BRIGHTNESS]

Expand Down Expand Up @@ -745,9 +750,10 @@ class DmxRGBW(DmxBaseLight):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self._supported_color_modes.add(COLOR_MODE_RGBW)
self._supported_color_modes.add(COLOR_MODE_HS)
self._features = SUPPORT_TRANSITION | SUPPORT_FLASH
self._color_mode = COLOR_MODE_RGBW
self._vals = (255, 255, 255, 255)
self._vals = [255, 255, 255, 255]

self._channel_setup = kwargs.get(CONF_CHANNEL_SETUP) or "rgbw"
validate(self._channel_setup, self.CONF_TYPE)
Expand All @@ -757,7 +763,7 @@ def __init__(self, **kwargs):
@property
def rgbw_color(self) -> tuple:
"""Return the rgbw color value."""
return self._vals
return tuple(self._vals)

def _update_values(self, values: array[int]):
self._state, self._attr_brightness, red, green, blue, white, _, _ = \
Expand Down Expand Up @@ -789,6 +795,10 @@ async def async_turn_on(self, **kwargs):
if ATTR_RGBW_COLOR in kwargs:
self._vals = kwargs[ATTR_RGBW_COLOR]

if ATTR_HS_COLOR in kwargs:
hue, sat = kwargs[ATTR_HS_COLOR]
self._vals[0:3] = list(color_util.color_hs_to_RGB(hue, sat))

if ATTR_BRIGHTNESS in kwargs:
self._attr_brightness = kwargs[ATTR_BRIGHTNESS]

Expand Down Expand Up @@ -819,30 +829,33 @@ class DmxRGBWW(DmxBaseLight):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self._supported_color_modes.add(COLOR_MODE_RGBWW)
self._supported_color_modes.add(COLOR_MODE_COLOR_TEMP)
self._supported_color_modes.add(COLOR_MODE_HS)

self._features = SUPPORT_TRANSITION | SUPPORT_FLASH
self._color_mode = COLOR_MODE_RGBWW
# Intentionally switching min and max here; it's inverted in the conversion.
self._min_kelvin = convert_to_kelvin(kwargs[CONF_DEVICE_MIN_TEMP])
self._max_kelvin = convert_to_kelvin(kwargs[CONF_DEVICE_MAX_TEMP])
self._vals = (255, 255, 255, 255, 255)
self._vals = [255, 255, 255, 255, 255, 0]

self._channel_setup = kwargs.get(CONF_CHANNEL_SETUP) or "rgbch"
validate(self._channel_setup, self.CONF_TYPE)

self._channel_width = len(self._channel_setup)

def _update_values(self, values: array[int]):
self._state, self._attr_brightness, red, green, blue, cold_white, warm_white, _ = \
self._state, self._attr_brightness, red, green, blue, cold_white, warm_white, color_temp = \
from_values(self._channel_setup, self.channel_size[1], values)

self._vals = (red, green, blue, cold_white, warm_white)
self._vals = (red, green, blue, cold_white, warm_white, color_temp)

self._channel_value_change()

@property
def rgbww_color(self) -> tuple:
"""Return the rgbww color value."""
return self._vals
return tuple(self._vals[0:5])

@property
def min_color_temp_kelvin(self) -> int:
Expand All @@ -856,36 +869,53 @@ def max_color_temp_kelvin(self) -> int:

@property
def color_temp_kelvin(self) -> int | None:
return color_util.rgbww_to_color_temperature(
self._vals, self.min_color_temp_kelvin, self.max_color_temp_kelvin)[0]
return self._vals[5]

def get_target_values(self):
red = self._vals[0]
green = self._vals[1]
blue = self._vals[2]
cold_white = self._vals[3]
warm_white = self._vals[4]
color_temperature_kelvin = self._vals[5]

return to_values(self._channel_setup, self._channel_size[1], self.is_on, self._attr_brightness,
red, green, blue, cold_white, warm_white,
color_temp_kelvin=color_temperature_kelvin,
min_kelvin=self.min_color_temp_kelvin,
max_kelvin=self.max_color_temp_kelvin)

async def async_turn_on(self, **kwargs):
"""
Instruct the light to turn on.
"""

old_values = self._vals
old_brightness = self._attr_brightness

# RGB already contains brightness information
if ATTR_RGBWW_COLOR in kwargs:
self._vals = kwargs[ATTR_RGBWW_COLOR]
self._vals[0:5] = kwargs[ATTR_RGBWW_COLOR]

if self._vals[3] != old_values[3] or self._vals[4] != old_values[4]:
self._vals[5], _ = color_util.rgbww_to_color_temperature(
(self._vals[0], self._vals[1], self._vals[2], self._vals[3], self._vals[4]),
self.min_color_temp_kelvin, self.max_color_temp_kelvin
)
self._channel_value_change()

if ATTR_HS_COLOR in kwargs:
hue, sat = kwargs[ATTR_HS_COLOR]
self._vals[0:3] = list(color_util.color_hs_to_RGB(hue, sat))

if ATTR_BRIGHTNESS in kwargs:
self._attr_brightness = kwargs[ATTR_BRIGHTNESS]

if ATTR_COLOR_TEMP_KELVIN in kwargs:
self._vals[5] = kwargs[ATTR_COLOR_TEMP_KELVIN]
_, _, _, self._vals[3], self._vals[4] = color_util.color_temperature_to_rgbww(
self._vals[5], self._attr_brightness, self.min_color_temp_kelvin, self.max_color_temp_kelvin)
self._channel_value_change()

if ATTR_FLASH in kwargs:
await super().flash(old_values, old_brightness, **kwargs)
else:
Expand Down
6 changes: 3 additions & 3 deletions custom_components/artnet_led/util/channel_switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ def to_values(channel_setup: str, channel_size: int, is_on: bool = True, brightn
"C": lambda: is_on * cold_white * 255 / max_color,
"h": lambda: is_on * warm_white * brightness / max_color,
"H": lambda: is_on * warm_white * 255 / max_color,
"t": lambda: 255 - (color_temp_kelvin - min_kelvin) * 255 / kelvin_diff,
"u": lambda: color_RGB_to_hsv(red, green ,blue)[0] * 255 / 360,
"T": lambda: (color_temp_kelvin - min_kelvin) * 255 / kelvin_diff,
"t": lambda: (color_temp_kelvin - min_kelvin) * 255 / kelvin_diff,
"T": lambda: 255 - (color_temp_kelvin - min_kelvin) * 255 / kelvin_diff,
"u": lambda: color_RGB_to_hsv(red, green, blue)[0] * 255 / 360,
"U": lambda: color_RGB_to_hsv(red, green, blue)[1] * 255 / 100,
}

Expand Down

0 comments on commit bc35ee8

Please sign in to comment.