Beispiel #1
0
    def parse_data(self, data, raw_data):
        """Parse data sent by gateway."""
        value = data.get(self._data_key)
        if value is None:
            return False

        if value == 0:
            if self._state:
                self._state = False
            return True

        rgbhexstr = "%x" % value
        if len(rgbhexstr) > 8:
            _LOGGER.error(
                "Light RGB data error."
                " Can't be more than 8 characters. Received: %s",
                rgbhexstr,
            )
            return False

        rgbhexstr = rgbhexstr.zfill(8)
        rgbhex = bytes.fromhex(rgbhexstr)
        rgba = struct.unpack("BBBB", rgbhex)
        brightness = rgba[0]
        rgb = rgba[1:]

        self._brightness = brightness
        self._hs = color_util.color_RGB_to_hs(*rgb)
        self._state = True
        return True
Beispiel #2
0
def find_hsbk(opp, **kwargs):
    """Find the desired color from a number of possible inputs."""
    hue, saturation, brightness, kelvin = [None] * 4

    preprocess_turn_on_alternatives(opp, kwargs)

    if ATTR_HS_COLOR in kwargs:
        hue, saturation = kwargs[ATTR_HS_COLOR]
    elif ATTR_RGB_COLOR in kwargs:
        hue, saturation = color_util.color_RGB_to_hs(*kwargs[ATTR_RGB_COLOR])
    elif ATTR_XY_COLOR in kwargs:
        hue, saturation = color_util.color_xy_to_hs(*kwargs[ATTR_XY_COLOR])

    if hue is not None:
        hue = int(hue / 360 * 65535)
        saturation = int(saturation / 100 * 65535)
        kelvin = 3500

    if ATTR_COLOR_TEMP in kwargs:
        kelvin = int(
            color_util.color_temperature_mired_to_kelvin(
                kwargs[ATTR_COLOR_TEMP]))
        saturation = 0

    if ATTR_BRIGHTNESS in kwargs:
        brightness = convert_8_to_16(kwargs[ATTR_BRIGHTNESS])

    hsbk = [hue, saturation, brightness, kelvin]
    return None if hsbk == [None] * 4 else hsbk
def preprocess_turn_on_alternatives(params):
    """Process extra data for turn light on request."""
    profile = Profiles.get(params.pop(ATTR_PROFILE, None))
    if profile is not None:
        params.setdefault(ATTR_XY_COLOR, profile[:2])
        params.setdefault(ATTR_BRIGHTNESS, profile[2])

    color_name = params.pop(ATTR_COLOR_NAME, None)
    if color_name is not None:
        try:
            params[ATTR_RGB_COLOR] = color_util.color_name_to_rgb(color_name)
        except ValueError:
            _LOGGER.warning("Got unknown color %s, falling back to white",
                            color_name)
            params[ATTR_RGB_COLOR] = (255, 255, 255)

    kelvin = params.pop(ATTR_KELVIN, None)
    if kelvin is not None:
        mired = color_util.color_temperature_kelvin_to_mired(kelvin)
        params[ATTR_COLOR_TEMP] = int(mired)

    brightness_pct = params.pop(ATTR_BRIGHTNESS_PCT, None)
    if brightness_pct is not None:
        params[ATTR_BRIGHTNESS] = int(255 * brightness_pct / 100)

    xy_color = params.pop(ATTR_XY_COLOR, None)
    if xy_color is not None:
        params[ATTR_HS_COLOR] = color_util.color_xy_to_hs(*xy_color)

    rgb_color = params.pop(ATTR_RGB_COLOR, None)
    if rgb_color is not None:
        params[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color)
Beispiel #4
0
    def _turn_on_rgb_and_w(self, hex_template, **kwargs):
        """Turn on RGB or RGBW child device."""
        rgb = list(color_util.color_hs_to_RGB(*self._hs))
        white = self._white
        hex_color = self._values.get(self.value_type)
        hs_color = kwargs.get(ATTR_HS_COLOR)
        if hs_color is not None:
            new_rgb = color_util.color_hs_to_RGB(*hs_color)
        else:
            new_rgb = None
        new_white = kwargs.get(ATTR_WHITE_VALUE)

        if new_rgb is None and new_white is None:
            return
        if new_rgb is not None:
            rgb = list(new_rgb)
        if hex_template == "%02x%02x%02x%02x":
            if new_white is not None:
                rgb.append(new_white)
            else:
                rgb.append(white)
        hex_color = hex_template % tuple(rgb)
        if len(rgb) > 3:
            white = rgb.pop()
        self.gateway.set_child_value(
            self.node_id, self.child_id, self.value_type, hex_color, ack=1
        )

        if self.assumed_state:
            # optimistically assume that light has changed state
            self._hs = color_util.color_RGB_to_hs(*rgb)
            self._white = white
            self._values[self.value_type] = hex_color
Beispiel #5
0
 def _async_update_rgb_or_w(self):
     """Update the controller with values from RGB or RGBW child."""
     value = self._values[self.value_type]
     color_list = rgb_hex_to_rgb_list(value)
     if len(color_list) > 3:
         self._white = color_list.pop()
     self._hs = color_util.color_RGB_to_hs(*color_list)
Beispiel #6
0
    async def async_update(self):
        """Fetch state from the device."""
        try:
            state = await self.opp.async_add_executor_job(self._device.status)
        except DeviceException as ex:
            if self._available:
                self._available = False
                _LOGGER.error("Got exception while fetching the state: %s", ex)

            return

        _LOGGER.debug("Got new state: %s", state)
        self._available = True
        self._state = state.is_on
        self._brightness = ceil((255 / 100.0) * state.brightness)
        self._color_temp = self.translate(state.color_temperature, CCT_MIN,
                                          CCT_MAX, self.max_mireds,
                                          self.min_mireds)
        self._hs_color = color.color_RGB_to_hs(*state.rgb)

        self._state_attrs.update({
            ATTR_SCENE: state.scene,
            ATTR_SLEEP_ASSISTANT: state.sleep_assistant,
            ATTR_SLEEP_OFF_TIME: state.sleep_off_time,
            ATTR_TOTAL_ASSISTANT_SLEEP_TIME: state.total_assistant_sleep_time,
            ATTR_BAND_SLEEP: state.brand_sleep,
            ATTR_BAND: state.brand,
        })
Beispiel #7
0
 def update(self) -> None:
     """Call to update state."""
     super().update()
     self._state = self.vera_device.is_switched_on()
     if self.vera_device.is_dimmable:
         # If it is dimmable, both functions exist. In case color
         # is not supported, it will return None
         self._brightness = self.vera_device.get_brightness()
         rgb = self.vera_device.get_color()
         self._color = color_util.color_RGB_to_hs(*rgb) if rgb else None
Beispiel #8
0
 def update(self):
     """Synchronise state from the bulb."""
     self._bulb.update()
     if self._bulb.power:
         self._brightness = self._bulb.brightness
         self._temp = self._bulb.temperature
         if self._bulb.colors:
             self._colormode = True
             self._hs = color_util.color_RGB_to_hs(*self._bulb.colors)
         else:
             self._colormode = False
     self._state = self._bulb.power
Beispiel #9
0
def _close_enough(actual_rgb, testing_rgb):
    """Validate the given RGB value is in acceptable tolerance."""
    # Convert the given RGB values to hue / saturation and then back again
    # as it wasn't reading the same RGB value set against it.
    actual_hs = color_util.color_RGB_to_hs(*actual_rgb)
    actual_rgb = color_util.color_hs_to_RGB(*actual_hs)

    testing_hs = color_util.color_RGB_to_hs(*testing_rgb)
    testing_rgb = color_util.color_hs_to_RGB(*testing_hs)

    actual_red, actual_green, actual_blue = actual_rgb
    testing_red, testing_green, testing_blue = testing_rgb

    r_diff = abs(actual_red - testing_red)
    g_diff = abs(actual_green - testing_green)
    b_diff = abs(actual_blue - testing_blue)

    return (
        r_diff <= CLOSE_THRESHOLD
        and g_diff <= CLOSE_THRESHOLD
        and b_diff <= CLOSE_THRESHOLD
    )
Beispiel #10
0
    def _calculate_color_values(self):
        """Parse color rgb and color temperature data."""
        # Color Data String
        data = self.values.color.data[ATTR_VALUE]

        # RGB is always present in the OpenZWave color data string.
        rgb = [int(data[1:3], 16), int(data[3:5], 16), int(data[5:7], 16)]
        self._hs = color_util.color_RGB_to_hs(*rgb)

        if self.values.color_channels is None:
            return

        # Color Channels
        self._color_channels = self.values.color_channels.data[ATTR_VALUE]

        # Parse remaining color channels. OpenZWave appends white channels
        # that are present.
        index = 7
        temp_warm = 0
        temp_cold = 0

        # Update color temp limits.
        if self.values.min_kelvin:
            self._max_mireds = color_util.color_temperature_kelvin_to_mired(
                self.values.min_kelvin.data[ATTR_VALUE])
        if self.values.max_kelvin:
            self._min_mireds = color_util.color_temperature_kelvin_to_mired(
                self.values.max_kelvin.data[ATTR_VALUE])

        # Warm white
        if self._color_channels & COLOR_CHANNEL_WARM_WHITE:
            self._white = int(data[index:index + 2], 16)
            temp_warm = self._white

        index += 2

        # Cold white
        if self._color_channels & COLOR_CHANNEL_COLD_WHITE:
            self._white = int(data[index:index + 2], 16)
            temp_cold = self._white

        # Calculate color temps based on white LED status
        if temp_cold or temp_warm:
            self._ct = round(self._max_mireds -
                             ((temp_cold / 255) *
                              (self._max_mireds - self._min_mireds)))

        if not (self._color_channels & COLOR_CHANNEL_RED
                or self._color_channels & COLOR_CHANNEL_GREEN
                or self._color_channels & COLOR_CHANNEL_BLUE):
            self._hs = None
Beispiel #11
0
 def _light_internal_convert_color(self, color_mode: str) -> dict:
     data: dict[str, tuple] = {}
     if color_mode == COLOR_MODE_HS and self.hs_color:
         hs_color = self.hs_color
         data[ATTR_HS_COLOR] = (round(hs_color[0],
                                      3), round(hs_color[1], 3))
         data[ATTR_RGB_COLOR] = color_util.color_hs_to_RGB(*hs_color)
         data[ATTR_XY_COLOR] = color_util.color_hs_to_xy(*hs_color)
     elif color_mode == COLOR_MODE_XY and self.xy_color:
         xy_color = self.xy_color
         data[ATTR_HS_COLOR] = color_util.color_xy_to_hs(*xy_color)
         data[ATTR_RGB_COLOR] = color_util.color_xy_to_RGB(*xy_color)
         data[ATTR_XY_COLOR] = (round(xy_color[0],
                                      6), round(xy_color[1], 6))
     elif color_mode == COLOR_MODE_RGB and self.rgb_color:
         rgb_color = self.rgb_color
         data[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color)
         data[ATTR_RGB_COLOR] = tuple(int(x) for x in rgb_color[0:3])
         data[ATTR_XY_COLOR] = color_util.color_RGB_to_xy(*rgb_color)
     elif color_mode == COLOR_MODE_RGBW and self._light_internal_rgbw_color:
         rgbw_color = self._light_internal_rgbw_color
         rgb_color = color_util.color_rgbw_to_rgb(*rgbw_color)
         data[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color)
         data[ATTR_RGB_COLOR] = tuple(int(x) for x in rgb_color[0:3])
         data[ATTR_RGBW_COLOR] = tuple(int(x) for x in rgbw_color[0:4])
         data[ATTR_XY_COLOR] = color_util.color_RGB_to_xy(*rgb_color)
     elif color_mode == COLOR_MODE_RGBWW and self.rgbww_color:
         rgbww_color = self.rgbww_color
         rgb_color = color_util.color_rgbww_to_rgb(*rgbww_color,
                                                   self.min_mireds,
                                                   self.max_mireds)
         data[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color)
         data[ATTR_RGB_COLOR] = tuple(int(x) for x in rgb_color[0:3])
         data[ATTR_RGBWW_COLOR] = tuple(int(x) for x in rgbww_color[0:5])
         data[ATTR_XY_COLOR] = color_util.color_RGB_to_xy(*rgb_color)
     return data
Beispiel #12
0
    async def async_handle_light_on_service(light, call):
        """Handle turning a light on.

        If brightness is set to 0, this service will turn the light off.
        """
        params = dict(call.data["params"])

        # Only process params once we processed brightness step
        if params and (ATTR_BRIGHTNESS_STEP in params
                       or ATTR_BRIGHTNESS_STEP_PCT in params):
            brightness = light.brightness if light.is_on else 0

            if ATTR_BRIGHTNESS_STEP in params:
                brightness += params.pop(ATTR_BRIGHTNESS_STEP)

            else:
                brightness += round(
                    params.pop(ATTR_BRIGHTNESS_STEP_PCT) / 100 * 255)

            params[ATTR_BRIGHTNESS] = max(0, min(255, brightness))

            preprocess_turn_on_alternatives(opp, params)

        if (not params or
                not light.is_on) or (params and ATTR_TRANSITION not in params):
            profiles.apply_default(light.entity_id, light.is_on, params)

        supported_color_modes = light.supported_color_modes
        # Backwards compatibility: if an RGBWW color is specified, convert to RGB + W
        # for legacy lights
        if ATTR_RGBW_COLOR in params:
            legacy_supported_color_modes = (
                light._light_internal_supported_color_modes  # pylint: disable=protected-access
            )
            if (COLOR_MODE_RGBW in legacy_supported_color_modes
                    and not supported_color_modes):
                rgbw_color = params.pop(ATTR_RGBW_COLOR)
                params[ATTR_RGB_COLOR] = rgbw_color[0:3]
                params[ATTR_WHITE_VALUE] = rgbw_color[3]

        # If a color is specified, convert to the color space supported by the light
        # Backwards compatibility: Fall back to hs color if light.supported_color_modes
        # is not implemented
        if not supported_color_modes:
            if (rgb_color := params.pop(ATTR_RGB_COLOR, None)) is not None:
                params[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color)
            elif (xy_color := params.pop(ATTR_XY_COLOR, None)) is not None:
                params[ATTR_HS_COLOR] = color_util.color_xy_to_hs(*xy_color)
Beispiel #13
0
    async def async_update(self):
        """Fetch state from the device."""
        try:
            state_dict = await self.opp.async_add_executor_job(
                self._gateway.light.rgb_status)
        except GatewayException as ex:
            if self._available:
                self._available = False
                _LOGGER.error(
                    "Got exception while fetching the gateway light state: %s",
                    ex)
            return

        self._available = True
        self._is_on = state_dict["is_on"]

        if self._is_on:
            self._brightness_pct = state_dict["brightness"]
            self._rgb = state_dict["rgb"]
            self._hs = color.color_RGB_to_hs(*self._rgb)
Beispiel #14
0
    def _get_hs_from_properties(self):
        rgb = self._get_property("rgb")
        color_mode = self._get_property("color_mode")

        if not rgb or not color_mode:
            return None

        color_mode = int(color_mode)
        if color_mode == 2:  # color temperature
            temp_in_k = mired_to_kelvin(self.color_temp)
            return color_util.color_temperature_to_hs(temp_in_k)
        if color_mode == 3:  # hsv
            hue = int(self._get_property("hue"))
            sat = int(self._get_property("sat"))

            return (hue / 360 * 65536, sat / 100 * 255)

        rgb = int(rgb)
        blue = rgb & 0xFF
        green = (rgb >> 8) & 0xFF
        red = (rgb >> 16) & 0xFF

        return color_util.color_RGB_to_hs(red, green, blue)
Beispiel #15
0
 def _update(self):
     """Really update the state."""
     # Brightness handling
     if self._supported_flags & SUPPORT_BRIGHTNESS:
         self._brightness = float(self.fibaro_device.properties.value)
         # Fibaro might report 0-99 or 0-100 for brightness,
         # based on device type, so we round up here
         if self._brightness > 99:
             self._brightness = 100
     # Color handling
     if (self._supported_flags & SUPPORT_COLOR
             and "color" in self.fibaro_device.properties
             and "," in self.fibaro_device.properties.color):
         # Fibaro communicates the color as an 'R, G, B, W' string
         rgbw_s = self.fibaro_device.properties.color
         if rgbw_s == "0,0,0,0" and "lastColorSet" in self.fibaro_device.properties:
             rgbw_s = self.fibaro_device.properties.lastColorSet
         rgbw_list = [int(i) for i in rgbw_s.split(",")][:4]
         if rgbw_list[0] or rgbw_list[1] or rgbw_list[2]:
             self._color = color_util.color_RGB_to_hs(*rgbw_list[:3])
         if (self._supported_flags
                 & SUPPORT_WHITE_VALUE) and self.brightness != 0:
             self._white = min(255, max(0, rgbw_list[3]))
Beispiel #16
0
 def hs_color(self):
     """Return the hs color value."""
     if self.device["status"]["mode"] == "COLOUR":
         rgb = self.device["status"].get("hs_color")
         return color_util.color_RGB_to_hs(*rgb)
     return None
Beispiel #17
0
 def hs_color(self):
     """Read back the hue-saturation of the light."""
     return color_util.color_RGB_to_hs(*self._rgb_color)
Beispiel #18
0
 def hs_color(self):
     """Return the color of the light."""
     return color_util.color_RGB_to_hs(*self._device.led_rgb)
Beispiel #19
0
 def hs_color(self):
     """Return last hs color value set."""
     return color_util.color_RGB_to_hs(*self._rgb_color)
Beispiel #20
0
 def hs_color(self):
     """Return the color property."""
     return color_util.color_RGB_to_hs(*self._rgb_color)
Beispiel #21
0
    def _update_color(self, values):
        if not self._config[CONF_COLOR_MODE]:
            # Deprecated color handling
            try:
                red = int(values["color"]["r"])
                green = int(values["color"]["g"])
                blue = int(values["color"]["b"])
                self._hs = color_util.color_RGB_to_hs(red, green, blue)
            except KeyError:
                pass
            except ValueError:
                _LOGGER.warning("Invalid RGB color value received")
                return

            try:
                x_color = float(values["color"]["x"])
                y_color = float(values["color"]["y"])
                self._hs = color_util.color_xy_to_hs(x_color, y_color)
            except KeyError:
                pass
            except ValueError:
                _LOGGER.warning("Invalid XY color value received")
                return

            try:
                hue = float(values["color"]["h"])
                saturation = float(values["color"]["s"])
                self._hs = (hue, saturation)
            except KeyError:
                pass
            except ValueError:
                _LOGGER.warning("Invalid HS color value received")
                return
        else:
            color_mode = values["color_mode"]
            if not self._supports_color_mode(color_mode):
                _LOGGER.warning("Invalid color mode received")
                return
            try:
                if color_mode == COLOR_MODE_COLOR_TEMP:
                    self._color_temp = int(values["color_temp"])
                    self._color_mode = COLOR_MODE_COLOR_TEMP
                elif color_mode == COLOR_MODE_HS:
                    hue = float(values["color"]["h"])
                    saturation = float(values["color"]["s"])
                    self._color_mode = COLOR_MODE_HS
                    self._hs = (hue, saturation)
                elif color_mode == COLOR_MODE_RGB:
                    r = int(values["color"]["r"])  # pylint: disable=invalid-name
                    g = int(values["color"]["g"])  # pylint: disable=invalid-name
                    b = int(values["color"]["b"])  # pylint: disable=invalid-name
                    self._color_mode = COLOR_MODE_RGB
                    self._rgb = (r, g, b)
                elif color_mode == COLOR_MODE_RGBW:
                    r = int(values["color"]["r"])  # pylint: disable=invalid-name
                    g = int(values["color"]["g"])  # pylint: disable=invalid-name
                    b = int(values["color"]["b"])  # pylint: disable=invalid-name
                    w = int(values["color"]["w"])  # pylint: disable=invalid-name
                    self._color_mode = COLOR_MODE_RGBW
                    self._rgbw = (r, g, b, w)
                elif color_mode == COLOR_MODE_RGBWW:
                    r = int(values["color"]["r"])  # pylint: disable=invalid-name
                    g = int(values["color"]["g"])  # pylint: disable=invalid-name
                    b = int(values["color"]["b"])  # pylint: disable=invalid-name
                    c = int(values["color"]["c"])  # pylint: disable=invalid-name
                    w = int(values["color"]["w"])  # pylint: disable=invalid-name
                    self._color_mode = COLOR_MODE_RGBWW
                    self._rgbww = (r, g, b, c, w)
                elif color_mode == COLOR_MODE_XY:
                    x = float(values["color"]["x"])  # pylint: disable=invalid-name
                    y = float(values["color"]["y"])  # pylint: disable=invalid-name
                    self._color_mode = COLOR_MODE_XY
                    self._xy = (x, y)
            except (KeyError, ValueError):
                _LOGGER.warning("Invalid or incomplete color value received")
Beispiel #22
0
 def hs_color(self):
     """Return the color property."""
     return color_util.color_RGB_to_hs(*self._bulb.getRgb())
        def state_received(msg):
            """Handle new MQTT messages."""
            values = json.loads(msg.payload)

            if values["state"] == "ON":
                self._state = True
            elif values["state"] == "OFF":
                self._state = False

            if self._hs is not None:
                try:
                    red = int(values["color"]["r"])
                    green = int(values["color"]["g"])
                    blue = int(values["color"]["b"])

                    self._hs = color_util.color_RGB_to_hs(red, green, blue)
                except KeyError:
                    pass
                except ValueError:
                    _LOGGER.warning("Invalid RGB color value received")

                try:
                    x_color = float(values["color"]["x"])
                    y_color = float(values["color"]["y"])

                    self._hs = color_util.color_xy_to_hs(x_color, y_color)
                except KeyError:
                    pass
                except ValueError:
                    _LOGGER.warning("Invalid XY color value received")

                try:
                    hue = float(values["color"]["h"])
                    saturation = float(values["color"]["s"])

                    self._hs = (hue, saturation)
                except KeyError:
                    pass
                except ValueError:
                    _LOGGER.warning("Invalid HS color value received")

            if self._brightness is not None:
                try:
                    self._brightness = int(
                        values["brightness"] /
                        float(self._config[CONF_BRIGHTNESS_SCALE]) * 255)
                except KeyError:
                    pass
                except ValueError:
                    _LOGGER.warning("Invalid brightness value received")

            if self._color_temp is not None:
                try:
                    self._color_temp = int(values["color_temp"])
                except KeyError:
                    pass
                except ValueError:
                    _LOGGER.warning("Invalid color temp value received")

            if self._effect is not None:
                try:
                    self._effect = values["effect"]
                except KeyError:
                    pass
                except ValueError:
                    _LOGGER.warning("Invalid effect value received")

            if self._white_value is not None:
                try:
                    self._white_value = int(values["white_value"])
                except KeyError:
                    pass
                except ValueError:
                    _LOGGER.warning("Invalid white value received")

            self.async_write_op_state()
Beispiel #24
0
 def hs_color(self) -> tuple[float, float]:
     """Return the hue and saturation color value [float, float]."""
     color = self.coordinator.data.state.segments[
         self._segment].color_primary
     return color_util.color_RGB_to_hs(*color[:3])
Beispiel #25
0
        def state_received(msg):
            """Handle new MQTT messages."""
            state = self._templates[
                CONF_STATE_TEMPLATE].async_render_with_possible_json_value(
                    msg.payload)
            if state == STATE_ON:
                self._state = True
            elif state == STATE_OFF:
                self._state = False
            else:
                _LOGGER.warning("Invalid state value received")

            if self._brightness is not None:
                try:
                    self._brightness = int(
                        self._templates[CONF_BRIGHTNESS_TEMPLATE].
                        async_render_with_possible_json_value(msg.payload))
                except ValueError:
                    _LOGGER.warning("Invalid brightness value received")

            if self._color_temp is not None:
                try:
                    self._color_temp = int(
                        self._templates[CONF_COLOR_TEMP_TEMPLATE].
                        async_render_with_possible_json_value(msg.payload))
                except ValueError:
                    _LOGGER.warning("Invalid color temperature value received")

            if self._hs is not None:
                try:
                    red = int(self._templates[CONF_RED_TEMPLATE].
                              async_render_with_possible_json_value(
                                  msg.payload))
                    green = int(self._templates[CONF_GREEN_TEMPLATE].
                                async_render_with_possible_json_value(
                                    msg.payload))
                    blue = int(self._templates[CONF_BLUE_TEMPLATE].
                               async_render_with_possible_json_value(
                                   msg.payload))
                    self._hs = color_util.color_RGB_to_hs(red, green, blue)
                except ValueError:
                    _LOGGER.warning("Invalid color value received")

            if self._white_value is not None:
                try:
                    self._white_value = int(
                        self._templates[CONF_WHITE_VALUE_TEMPLATE].
                        async_render_with_possible_json_value(msg.payload))
                except ValueError:
                    _LOGGER.warning("Invalid white value received")

            if self._templates[CONF_EFFECT_TEMPLATE] is not None:
                effect = self._templates[
                    CONF_EFFECT_TEMPLATE].async_render_with_possible_json_value(
                        msg.payload)

                if effect in self._config.get(CONF_EFFECT_LIST):
                    self._effect = effect
                else:
                    _LOGGER.warning("Unsupported effect value received")

            self.async_write_op_state()
Beispiel #26
0
 def hs_color(self):
     """Return the hs value."""
     return color_util.color_RGB_to_hs(*self._lamp.state()["rgb"])
Beispiel #27
0
    def _calculate_color_values(self) -> None:
        """Calculate light colors."""
        # NOTE: We lookup all values here (instead of relying on the multicolor one)
        # to find out what colors are supported
        # as this is a simple lookup by key, this not heavy
        red_val = self.get_zwave_value(
            "currentColor",
            CommandClass.SWITCH_COLOR,
            value_property_key=ColorComponent.RED.value,
        )
        green_val = self.get_zwave_value(
            "currentColor",
            CommandClass.SWITCH_COLOR,
            value_property_key=ColorComponent.GREEN.value,
        )
        blue_val = self.get_zwave_value(
            "currentColor",
            CommandClass.SWITCH_COLOR,
            value_property_key=ColorComponent.BLUE.value,
        )
        ww_val = self.get_zwave_value(
            "currentColor",
            CommandClass.SWITCH_COLOR,
            value_property_key=ColorComponent.WARM_WHITE.value,
        )
        cw_val = self.get_zwave_value(
            "currentColor",
            CommandClass.SWITCH_COLOR,
            value_property_key=ColorComponent.COLD_WHITE.value,
        )
        # prefer the (new) combined color property
        # https://github.com/zwave-js/node-zwave-js/pull/1782
        combined_color_val = self.get_zwave_value(
            "currentColor",
            CommandClass.SWITCH_COLOR,
            value_property_key=None,
        )
        if combined_color_val and isinstance(combined_color_val.value, dict):
            multi_color = combined_color_val.value
        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
            red = multi_color.get("red", red_val.value)
            green = multi_color.get("green", green_val.value)
            blue = multi_color.get("blue", blue_val.value)
            self._supports_color = True
            if None not in (red, green, blue):
                # 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

        # color temperature support
        if ww_val and cw_val:
            self._supports_color_temp = True
            warm_white = multi_color.get("warmWhite", ww_val.value)
            cold_white = multi_color.get("coldWhite", cw_val.value)
            # Calculate color temps based on whites
            if cold_white or warm_white:
                self._color_temp = round(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
            else:
                self._color_temp = None
        # 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_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
Beispiel #28
0
 def hs_color(self):
     """Return the hue and saturation color value [float, float]."""
     return color_util.color_RGB_to_hs(self._red, self._green, self._blue)
Beispiel #29
0
    def update_properties(self):
        """Update internal properties based on zwave values."""
        super().update_properties()

        if self.values.color is None:
            return
        if self.values.color_channels is None:
            return

        # Color Channels
        self._color_channels = self.values.color_channels.data

        # Color Data String
        data = self.values.color.data

        # RGB is always present in the openzwave color data string.
        rgb = [int(data[1:3], 16), int(data[3:5], 16), int(data[5:7], 16)]
        self._hs = color_util.color_RGB_to_hs(*rgb)

        # Parse remaining color channels. Openzwave appends white channels
        # that are present.
        index = 7

        # Warm white
        if self._color_channels & COLOR_CHANNEL_WARM_WHITE:
            warm_white = int(data[index:index + 2], 16)
            index += 2
        else:
            warm_white = 0

        # Cold white
        if self._color_channels & COLOR_CHANNEL_COLD_WHITE:
            cold_white = int(data[index:index + 2], 16)
            index += 2
        else:
            cold_white = 0

        # Color temperature. With the AEOTEC ZW098 bulb, only two color
        # temperatures are supported. The warm and cold channel values
        # indicate brightness for warm/cold color temperature.
        if self._zw098:
            if warm_white > 0:
                self._ct = TEMP_WARM_OPP
                self._hs = ct_to_hs(self._ct)
            elif cold_white > 0:
                self._ct = TEMP_COLD_OPP
                self._hs = ct_to_hs(self._ct)
            else:
                # RGB color is being used. Just report midpoint.
                self._ct = TEMP_MID_OPP

        elif self._color_channels & COLOR_CHANNEL_WARM_WHITE:
            self._white = warm_white

        elif self._color_channels & COLOR_CHANNEL_COLD_WHITE:
            self._white = cold_white

        # If no rgb channels supported, report None.
        if not (self._color_channels & COLOR_CHANNEL_RED
                or self._color_channels & COLOR_CHANNEL_GREEN
                or self._color_channels & COLOR_CHANNEL_BLUE):
            self._hs = None
Beispiel #30
0
 def hs_color(self) -> tuple[float, float]:
     """Return last color value set."""
     return color_util.color_RGB_to_hs(*self._rgb_color)