-
-
Notifications
You must be signed in to change notification settings - Fork 37.5k
Add color_mode support to zwave_js light #49588
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,14 +11,14 @@ | |
| ATTR_BRIGHTNESS, | ||
| ATTR_COLOR_TEMP, | ||
| ATTR_HS_COLOR, | ||
| ATTR_RGBW_COLOR, | ||
| ATTR_TRANSITION, | ||
| ATTR_WHITE_VALUE, | ||
| COLOR_MODE_BRIGHTNESS, | ||
| COLOR_MODE_COLOR_TEMP, | ||
| COLOR_MODE_HS, | ||
| COLOR_MODE_RGBW, | ||
| DOMAIN as LIGHT_DOMAIN, | ||
| SUPPORT_BRIGHTNESS, | ||
| SUPPORT_COLOR, | ||
| SUPPORT_COLOR_TEMP, | ||
| SUPPORT_TRANSITION, | ||
| SUPPORT_WHITE_VALUE, | ||
| LightEntity, | ||
| ) | ||
| from homeassistant.config_entries import ConfigEntry | ||
|
|
@@ -85,14 +85,14 @@ def __init__( | |
| """Initialize the light.""" | ||
| super().__init__(config_entry, client, info) | ||
| self._supports_color = False | ||
| self._supports_white_value = False | ||
| self._supports_rgbw = False | ||
| self._supports_color_temp = False | ||
| self._hs_color: tuple[float, float] | None = None | ||
| self._white_value: int | None = None | ||
| self._rgbw_color: tuple[int, int, int, int] | None = None | ||
| self._color_mode: str | None = None | ||
| self._color_temp: int | None = None | ||
| self._min_mireds = 153 # 6500K as a safe default | ||
| self._max_mireds = 370 # 2700K as a safe default | ||
| self._supported_features = SUPPORT_BRIGHTNESS | ||
| self._warm_white = self.get_zwave_value( | ||
| "targetColor", | ||
| CommandClass.SWITCH_COLOR, | ||
|
|
@@ -103,19 +103,23 @@ def __init__( | |
| CommandClass.SWITCH_COLOR, | ||
| value_property_key=ColorComponent.COLD_WHITE, | ||
| ) | ||
| self._supported_color_modes = set() | ||
| self._supported_features = 0 | ||
|
|
||
| # get additional (optional) values and set features | ||
| self._target_value = self.get_zwave_value("targetValue") | ||
| self._dimming_duration = self.get_zwave_value("duration") | ||
| if self._dimming_duration is not None: | ||
| self._supported_features |= SUPPORT_TRANSITION | ||
| self._calculate_color_values() | ||
| if self._supports_color: | ||
| self._supported_features |= SUPPORT_COLOR | ||
| if self._supports_rgbw: | ||
| self._supported_color_modes.add(COLOR_MODE_RGBW) | ||
| elif self._supports_color: | ||
| self._supported_color_modes.add(COLOR_MODE_HS) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. zwave is using raw RGB internally, we might want to flag COLOR_MODE_RGB instead. |
||
| if self._supports_color_temp: | ||
| self._supported_features |= SUPPORT_COLOR_TEMP | ||
| if self._supports_white_value: | ||
| self._supported_features |= SUPPORT_WHITE_VALUE | ||
| self._supported_color_modes.add(COLOR_MODE_COLOR_TEMP) | ||
| if not self._supported_color_modes: | ||
| self._supported_color_modes.add(COLOR_MODE_BRIGHTNESS) | ||
|
|
||
| @callback | ||
| def on_value_update(self) -> None: | ||
|
|
@@ -132,6 +136,11 @@ def brightness(self) -> int: | |
| return round((self.info.primary_value.value / 99) * 255) | ||
| return 0 | ||
|
|
||
| @property | ||
| def color_mode(self) -> str | None: | ||
| """Return the color mode of the light.""" | ||
| return self._color_mode | ||
|
|
||
| @property | ||
| def is_on(self) -> bool: | ||
| """Return true if device is on (brightness above 0).""" | ||
|
|
@@ -143,9 +152,9 @@ def hs_color(self) -> tuple[float, float] | None: | |
| return self._hs_color | ||
|
|
||
| @property | ||
| def white_value(self) -> int | None: | ||
| """Return the white value of this light between 0..255.""" | ||
| return self._white_value | ||
| def rgbw_color(self) -> tuple[int, int, int, int] | None: | ||
| """Return the hs color.""" | ||
| return self._rgbw_color | ||
|
|
||
| @property | ||
| def color_temp(self) -> int | None: | ||
|
|
@@ -162,6 +171,11 @@ def max_mireds(self) -> int: | |
| """Return the warmest color_temp that this light supports.""" | ||
| return self._max_mireds | ||
|
|
||
| @property | ||
| def supported_color_modes(self) -> set | None: | ||
|
emontnemery marked this conversation as resolved.
|
||
| """Flag supported features.""" | ||
| return self._supported_color_modes | ||
|
|
||
| @property | ||
| def supported_features(self) -> int: | ||
| """Flag supported features.""" | ||
|
|
@@ -211,20 +225,20 @@ async def async_turn_on(self, **kwargs: Any) -> None: | |
| } | ||
| ) | ||
|
|
||
| # White value | ||
| white_value = kwargs.get(ATTR_WHITE_VALUE) | ||
| if white_value is not None and self._supports_white_value: | ||
| # white led brightness is controlled by white level | ||
| # rgb leds (if any) can be on at the same time | ||
| white_channel = {} | ||
|
|
||
| # RGBW | ||
| rgbw = kwargs.get(ATTR_RGBW_COLOR) | ||
| if rgbw is not None and self._supports_rgbw: | ||
| rgbw_channels = { | ||
| ColorComponent.RED: rgbw[0], | ||
| ColorComponent.GREEN: rgbw[1], | ||
| ColorComponent.BLUE: rgbw[2], | ||
| } | ||
| if self._warm_white: | ||
| white_channel[ColorComponent.WARM_WHITE] = white_value | ||
| rgbw_channels[ColorComponent.WARM_WHITE] = rgbw[3] | ||
|
|
||
| if self._cold_white: | ||
| white_channel[ColorComponent.COLD_WHITE] = white_value | ||
|
|
||
| await self._async_set_colors(white_channel) | ||
| rgbw_channels[ColorComponent.COLD_WHITE] = rgbw[3] | ||
| await self._async_set_colors(rgbw_channels) | ||
|
|
||
| # set brightness | ||
| await self._async_set_brightness( | ||
|
|
@@ -361,6 +375,9 @@ def _calculate_color_values(self) -> None: | |
| else: | ||
| multi_color = {} | ||
|
|
||
| # Default: Brightness (no color) | ||
| self._color_mode = COLOR_MODE_BRIGHTNESS | ||
|
|
||
| # RGB support | ||
| if red_val and green_val and blue_val: | ||
| # prefer values from the multicolor property | ||
|
|
@@ -370,6 +387,8 @@ def _calculate_color_values(self) -> None: | |
| self._supports_color = True | ||
| # convert to HS | ||
| self._hs_color = color_util.color_RGB_to_hs(red, green, blue) | ||
| # Light supports color, set color mode to hs | ||
| self._color_mode = COLOR_MODE_HS | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. zwave is using raw RGB internally, we might want to flag |
||
|
|
||
| # color temperature support | ||
| if ww_val and cw_val: | ||
|
|
@@ -382,13 +401,21 @@ def _calculate_color_values(self) -> None: | |
| self._max_mireds | ||
| - ((cold_white / 255) * (self._max_mireds - self._min_mireds)) | ||
| ) | ||
| # White channels turned on, set color mode to color_temp | ||
| self._color_mode = COLOR_MODE_COLOR_TEMP | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. zwave allows all 5 channels in a 5 channel light to be on simultaneously. Unless blocked by zwave_js, we might want to check which channels are on: |
||
| else: | ||
| self._color_temp = None | ||
| # only one white channel (warm white) = white_level support | ||
| elif ww_val: | ||
| self._supports_white_value = True | ||
| self._white_value = multi_color.get("warmWhite", ww_val.value) | ||
| # only one white channel (cool white) = white_level support | ||
| # only one white channel (warm white) = rgbw support | ||
| elif red_val and green_val and blue_val and ww_val: | ||
| self._supports_rgbw = True | ||
| white = multi_color.get("warmWhite", ww_val.value) | ||
| self._rgbw_color = (red, green, blue, white) | ||
| # Light supports rgbw, set color mode to rgbw | ||
| self._color_mode = COLOR_MODE_RGBW | ||
| # only one white channel (cool white) = rgbw support | ||
| elif cw_val: | ||
| self._supports_white_value = True | ||
| self._white_value = multi_color.get("coldWhite", cw_val.value) | ||
| self._supports_rgbw = True | ||
| white = multi_color.get("coldWhite", cw_val.value) | ||
| self._rgbw_color = (red, green, blue, white) | ||
| # Light supports rgbw, set color mode to rgbw | ||
| self._color_mode = COLOR_MODE_RGBW | ||
Uh oh!
There was an error while loading. Please reload this page.