Ejemplo n.º 1
0
    async def async_update(self):
        """Retrieve latest state."""
        result = await zha.safe_read(self._endpoint.on_off, ['on_off'],
                                     allow_cache=False,
                                     only_cache=(not self._initialized))
        self._state = result.get('on_off', self._state)

        if self._supported_features & light.SUPPORT_BRIGHTNESS:
            result = await zha.safe_read(self._endpoint.level,
                                         ['current_level'],
                                         allow_cache=False,
                                         only_cache=(not self._initialized))
            self._brightness = result.get('current_level', self._brightness)

        if self._supported_features & light.SUPPORT_COLOR_TEMP:
            result = await zha.safe_read(self._endpoint.light_color,
                                         ['color_temperature'],
                                         allow_cache=False,
                                         only_cache=(not self._initialized))
            self._color_temp = result.get('color_temperature',
                                          self._color_temp)

        if self._supported_features & light.SUPPORT_COLOR:
            result = await zha.safe_read(self._endpoint.light_color,
                                         ['current_x', 'current_y'],
                                         allow_cache=False,
                                         only_cache=(not self._initialized))
            if 'current_x' in result and 'current_y' in result:
                xy_color = (round(result['current_x']/65535, 3),
                            round(result['current_y']/65535, 3))
                self._hs_color = color_util.color_xy_to_hs(*xy_color)
Ejemplo n.º 2
0
    def test_color_xy_to_hs(self):
        """Test color_xy_to_hs."""
        self.assertEqual((47.294, 100),
                         color_util.color_xy_to_hs(1, 1))

        self.assertEqual((38.182, 12.941),
                         color_util.color_xy_to_hs(.35, .35))

        self.assertEqual((345.882, 100),
                         color_util.color_xy_to_hs(1, 0))

        self.assertEqual((120, 100),
                         color_util.color_xy_to_hs(0, 1))

        self.assertEqual((225.176, 100),
                         color_util.color_xy_to_hs(0, 0))
Ejemplo n.º 3
0
def find_hsbk(**kwargs):
    """Find the desired color from a number of possible inputs."""
    hue, saturation, brightness, kelvin = [None]*4

    preprocess_turn_on_alternatives(kwargs)

    if ATTR_RGB_COLOR in kwargs:
        hue, saturation, brightness = \
            color_util.color_RGB_to_hsv(*kwargs[ATTR_RGB_COLOR])
        saturation = convert_8_to_16(saturation)
        brightness = convert_8_to_16(brightness)
        kelvin = 3500

    if ATTR_XY_COLOR in kwargs:
        hue, saturation = color_util.color_xy_to_hs(*kwargs[ATTR_XY_COLOR])
        saturation = convert_8_to_16(saturation)
        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
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
    def test_color_xy_to_hs(self):
        """Test color_xy_to_hs."""
        self.assertEqual((8609, 255),
                         color_util.color_xy_to_hs(1, 1))

        self.assertEqual((6950, 32),
                         color_util.color_xy_to_hs(.35, .35))

        self.assertEqual((62965, 255),
                         color_util.color_xy_to_hs(1, 0))

        self.assertEqual((21845, 255),
                         color_util.color_xy_to_hs(0, 1))

        self.assertEqual((40992, 255),
                         color_util.color_xy_to_hs(0, 0))
Ejemplo n.º 6
0
    def turn_on(self, **kwargs):
        """Turn the specified or all lights on."""
        command = {'on': True}

        if ATTR_TRANSITION in kwargs:
            command['transitiontime'] = int(kwargs[ATTR_TRANSITION] * 10)

        if ATTR_XY_COLOR in kwargs:
            if self.info.get('manufacturername') == "OSRAM":
                hue, sat = color_util.color_xy_to_hs(*kwargs[ATTR_XY_COLOR])
                command['hue'] = hue
                command['sat'] = sat
                command['bri'] = self.info['bri']
            else:
                command['xy'] = kwargs[ATTR_XY_COLOR]
        elif ATTR_RGB_COLOR in kwargs:
            if self.info.get('manufacturername') == "OSRAM":
                hsv = color_util.color_RGB_to_hsv(
                    *(int(val) for val in kwargs[ATTR_RGB_COLOR]))
                command['hue'] = hsv[0]
                command['sat'] = hsv[1]
                command['bri'] = hsv[2]
            else:
                xyb = color_util.color_RGB_to_xy(
                    *(int(val) for val in kwargs[ATTR_RGB_COLOR]))
                command['xy'] = xyb[0], xyb[1]
                command['bri'] = xyb[2]

        if ATTR_BRIGHTNESS in kwargs:
            command['bri'] = kwargs[ATTR_BRIGHTNESS]

        if ATTR_COLOR_TEMP in kwargs:
            temp = kwargs[ATTR_COLOR_TEMP]
            command['ct'] = max(self.min_mireds, min(temp, self.max_mireds))

        flash = kwargs.get(ATTR_FLASH)

        if flash == FLASH_LONG:
            command['alert'] = 'lselect'
            del command['on']
        elif flash == FLASH_SHORT:
            command['alert'] = 'select'
            del command['on']
        elif self.bridge_type == 'hue':
            command['alert'] = 'none'

        effect = kwargs.get(ATTR_EFFECT)

        if effect == EFFECT_COLORLOOP:
            command['effect'] = 'colorloop'
        elif effect == EFFECT_RANDOM:
            command['hue'] = random.randrange(0, 65535)
            command['sat'] = random.randrange(150, 254)
        elif self.bridge_type == 'hue':
            if self.info.get('manufacturername') != "OSRAM":
                command['effect'] = 'none'

        self._command_func(self.light_id, command)
Ejemplo n.º 7
0
    def turn_on(self, **kwargs):
        """Turn the specified or all lights on."""
        command = {'on': True}

        if ATTR_TRANSITION in kwargs:
            command['transitiontime'] = int(kwargs[ATTR_TRANSITION] * 10)

        if ATTR_XY_COLOR in kwargs:
            if self.info.get('manufacturername') == 'OSRAM':
                color_hue, sat = color_util.color_xy_to_hs(
                    *kwargs[ATTR_XY_COLOR])
                command['hue'] = color_hue
                command['sat'] = sat
            else:
                command['xy'] = kwargs[ATTR_XY_COLOR]
        elif ATTR_RGB_COLOR in kwargs:
            if self.info.get('manufacturername') == 'OSRAM':
                hsv = color_util.color_RGB_to_hsv(
                    *(int(val) for val in kwargs[ATTR_RGB_COLOR]))
                command['hue'] = hsv[0]
                command['sat'] = hsv[1]
                command['bri'] = hsv[2]
            else:
                xyb = color_util.color_RGB_to_xy(
                    *(int(val) for val in kwargs[ATTR_RGB_COLOR]))
                command['xy'] = xyb[0], xyb[1]
                command['bri'] = xyb[2]
        elif ATTR_COLOR_TEMP in kwargs:
            temp = kwargs[ATTR_COLOR_TEMP]
            command['ct'] = max(self.min_mireds, min(temp, self.max_mireds))

        if ATTR_BRIGHTNESS in kwargs:
            command['bri'] = kwargs[ATTR_BRIGHTNESS]

        flash = kwargs.get(ATTR_FLASH)

        if flash == FLASH_LONG:
            command['alert'] = 'lselect'
            del command['on']
        elif flash == FLASH_SHORT:
            command['alert'] = 'select'
            del command['on']
        elif self.bridge_type == 'hue':
            command['alert'] = 'none'

        effect = kwargs.get(ATTR_EFFECT)

        if effect == EFFECT_COLORLOOP:
            command['effect'] = 'colorloop'
        elif effect == EFFECT_RANDOM:
            command['hue'] = random.randrange(0, 65535)
            command['sat'] = random.randrange(150, 254)
        elif (self.bridge_type == 'hue'
              and self.info.get('manufacturername') == 'Philips'):
            command['effect'] = 'none'

        self._command_func(self.light_id, command)
Ejemplo n.º 8
0
    def hs_color(self):
        """Return the hs color value."""
        mode = self._color_mode
        source = self.light.action if self.is_group else self.light.state

        if mode in ("xy", "hs") and "xy" in source:
            return color.color_xy_to_hs(*source["xy"], self.gamut)

        return None
Ejemplo n.º 9
0
 def hs_color(self):
     """Return the hs color value."""
     if self._device.colormode in ("xy", "hs"):
         if self._device.xy:
             return color_util.color_xy_to_hs(*self._device.xy)
         if self._device.hue and self._device.sat:
             return (self._device.hue / 65535 * 360,
                     self._device.sat / 255 * 100)
     return None
Ejemplo n.º 10
0
    def hs_color(self):
        """Return the hs color value."""
        mode = self._color_mode
        source = self.light.action if self.is_group else self.light.state

        if mode in ('xy', 'hs') and 'xy' in source:
            return color.color_xy_to_hs(*source['xy'], self.gamut)

        return None
Ejemplo n.º 11
0
    def __post_init__(self) -> None:
        """Convert xy to hs color."""
        if None in (self.color_x, self.color_y):
            self.hs_color = None
            return

        self.hs_color = color_util.color_xy_to_hs(
            cast(float, self.color_x), cast(float, self.color_y)
        )
Ejemplo n.º 12
0
    def hs_color(self):
        """Return the hs color value."""
        mode = self._color_mode
        source = self.light.action if self.is_group else self.light.state

        if mode in ('xy', 'hs') and 'xy' in source:
            return color.color_xy_to_hs(*source['xy'])

        return None
Ejemplo n.º 13
0
def test_hs_color():
    """Test hs_color property."""
    light = hue_light.HueLight(
        light=Mock(
            state={
                "colormode": "ct",
                "hue": 1234,
                "sat": 123
            },
            raw=LIGHT_RAW,
            colorgamuttype=LIGHT_GAMUT_TYPE,
            colorgamut=LIGHT_GAMUT,
        ),
        request_bridge_update=None,
        bridge=Mock(),
        is_group=False,
    )

    assert light.hs_color is None

    light = hue_light.HueLight(
        light=Mock(
            state={
                "colormode": "hs",
                "hue": 1234,
                "sat": 123
            },
            raw=LIGHT_RAW,
            colorgamuttype=LIGHT_GAMUT_TYPE,
            colorgamut=LIGHT_GAMUT,
        ),
        request_bridge_update=None,
        bridge=Mock(),
        is_group=False,
    )

    assert light.hs_color is None

    light = hue_light.HueLight(
        light=Mock(
            state={
                "colormode": "xy",
                "hue": 1234,
                "sat": 123,
                "xy": [0.4, 0.5]
            },
            raw=LIGHT_RAW,
            colorgamuttype=LIGHT_GAMUT_TYPE,
            colorgamut=LIGHT_GAMUT,
        ),
        request_bridge_update=None,
        bridge=Mock(),
        is_group=False,
    )

    assert light.hs_color == color.color_xy_to_hs(0.4, 0.5, LIGHT_GAMUT)
Ejemplo n.º 14
0
        def xy_received(msg):
            """Handle new MQTT messages for xy color."""
            payload = templates[CONF_XY](msg.payload)
            if not payload:
                _LOGGER.debug("Ignoring empty xy-color message from '%s'", msg.topic)
                return

            xy_color = [float(val) for val in payload.split(",")]
            self._hs = color_util.color_xy_to_hs(*xy_color)
            self.async_write_ha_state()
Ejemplo n.º 15
0
        def xy_received(topic, payload, qos):
            """Handle new MQTT messages for xy color."""
            payload = templates[CONF_XY](payload)
            if not payload:
                _LOGGER.debug("Ignoring empty xy-color message from '%s'",
                              topic)
                return

            xy_color = [float(val) for val in payload.split(',')]
            self._hs = color_util.color_xy_to_hs(*xy_color)
            self.async_schedule_update_ha_state()
Ejemplo n.º 16
0
    def __init__(self, unique_id, zha_device: ZhaDeviceType, channels,
                 **kwargs):
        """Initialize the ZHA light."""
        super().__init__(unique_id, zha_device, channels, **kwargs)
        self._on_off_channel = self.cluster_channels.get(CHANNEL_ON_OFF)
        self._state = bool(self._on_off_channel.on_off)
        self._level_channel = self.cluster_channels.get(CHANNEL_LEVEL)
        self._color_channel = self.cluster_channels.get(CHANNEL_COLOR)
        self._identify_channel = self.zha_device.channels.identify_ch
        if self._color_channel:
            self._min_mireds: int | None = self._color_channel.min_mireds
            self._max_mireds: int | None = self._color_channel.max_mireds
        self._cancel_refresh_handle = None
        effect_list = []

        if self._level_channel:
            self._supported_features |= light.SUPPORT_BRIGHTNESS
            self._supported_features |= light.SUPPORT_TRANSITION
            self._brightness = self._level_channel.current_level

        if self._color_channel:
            color_capabilities = self._color_channel.color_capabilities
            if color_capabilities & CAPABILITIES_COLOR_TEMP:
                self._supported_features |= light.SUPPORT_COLOR_TEMP
                self._color_temp = self._color_channel.color_temperature

            if color_capabilities & CAPABILITIES_COLOR_XY:
                self._supported_features |= light.SUPPORT_COLOR
                curr_x = self._color_channel.current_x
                curr_y = self._color_channel.current_y
                if curr_x is not None and curr_y is not None:
                    self._hs_color = color_util.color_xy_to_hs(
                        float(curr_x / 65535), float(curr_y / 65535))
                else:
                    self._hs_color = (0, 0)

            if color_capabilities & CAPABILITIES_COLOR_LOOP:
                self._supported_features |= light.SUPPORT_EFFECT
                effect_list.append(light.EFFECT_COLORLOOP)
                if self._color_channel.color_loop_active == 1:
                    self._effect = light.EFFECT_COLORLOOP

        if self._identify_channel:
            self._supported_features |= light.SUPPORT_FLASH

        if effect_list:
            self._effect_list = effect_list

        self._default_transition = async_get_zha_config_value(
            zha_device.gateway.config_entry,
            ZHA_OPTIONS,
            CONF_DEFAULT_LIGHT_TRANSITION,
            0,
        )
Ejemplo n.º 17
0
def test_hs_color():
    """Test hs_color property."""
    light = hue_light.HueLight(
        light=Mock(state={
            'colormode': 'ct',
            'hue': 1234,
            'sat': 123,
        }),
        request_bridge_update=None,
        bridge=Mock(),
        is_group=False,
    )

    assert light.hs_color is None

    light = hue_light.HueLight(
        light=Mock(state={
            'colormode': 'hs',
            'hue': 1234,
            'sat': 123,
        }),
        request_bridge_update=None,
        bridge=Mock(),
        is_group=False,
    )

    assert light.hs_color == (1234 / 65535 * 360, 123 / 255 * 100)

    light = hue_light.HueLight(
        light=Mock(state={
            'colormode': 'xy',
            'hue': 1234,
            'sat': 123,
        }),
        request_bridge_update=None,
        bridge=Mock(),
        is_group=False,
    )

    assert light.hs_color == (1234 / 65535 * 360, 123 / 255 * 100)

    light = hue_light.HueLight(
        light=Mock(state={
            'colormode': 'xy',
            'hue': None,
            'sat': 123,
            'xy': [0.4, 0.5]
        }),
        request_bridge_update=None,
        bridge=Mock(),
        is_group=False,
    )

    assert light.hs_color == color.color_xy_to_hs(0.4, 0.5)
Ejemplo n.º 18
0
        def xy_received(msg):
            """Handle new MQTT messages for xy color."""
            payload = templates[CONF_XY](msg.payload)
            if not payload:
                _LOGGER.debug("Ignoring empty xy-color message from '%s'",
                              msg.topic)
                return

            xy_color = [float(val) for val in payload.split(',')]
            self._hs = color_util.color_xy_to_hs(*xy_color)
            self.async_write_ha_state()
Ejemplo n.º 19
0
    def hs_color(self):
        """Define current bulb color."""
        if self.wink.supports_xy_color():
            return color_util.color_xy_to_hs(*self.wink.color_xy())

        if self.wink.supports_hue_saturation():
            hue = self.wink.color_hue()
            saturation = self.wink.color_saturation()
            if hue is not None and saturation is not None:
                return hue * 360, saturation * 100

        return None
Ejemplo n.º 20
0
    def hs_color(self):
        """Define current bulb color."""
        if self.wink.supports_xy_color():
            return color_util.color_xy_to_hs(*self.wink.color_xy())

        if self.wink.supports_hue_saturation():
            hue = self.wink.color_hue()
            saturation = self.wink.color_saturation()
            if hue is not None and saturation is not None:
                return hue*360, saturation*100

        return None
Ejemplo n.º 21
0
    async def async_get_state(self):
        """Attempt to retrieve the state from the light."""
        if not self.available:
            return
        self.debug("polling current state")
        if self._on_off_channel:
            state = await self._on_off_channel.get_attribute_value(
                "on_off", from_cache=False
            )
            if state is not None:
                self._state = state
        if self._level_channel:
            level = await self._level_channel.get_attribute_value(
                "current_level", from_cache=False
            )
            if level is not None:
                self._brightness = level
        if self._color_channel:
            attributes = [
                "color_mode",
                "color_temperature",
                "current_x",
                "current_y",
                "color_loop_active",
            ]

            results = await self._color_channel.get_attributes(
                attributes, from_cache=False
            )

            color_mode = results.get("color_mode")
            if color_mode is not None:
                if color_mode == LightColorMode.COLOR_TEMP:
                    color_temp = results.get("color_temperature")
                    if color_temp is not None and color_mode:
                        self._color_temp = color_temp
                        self._hs_color = None
                else:
                    color_x = results.get("current_x")
                    color_y = results.get("current_y")
                    if color_x is not None and color_y is not None:
                        self._hs_color = color_util.color_xy_to_hs(
                            float(color_x / 65535), float(color_y / 65535)
                        )
                        self._color_temp = None

            color_loop_active = results.get("color_loop_active")
            if color_loop_active is not None:
                if color_loop_active == 1:
                    self._effect = light.EFFECT_COLORLOOP
                else:
                    self._effect = None
Ejemplo n.º 22
0
async def test_default_profiles_light(hass, mock_light_profiles):
    """Test default turn-on light profile for a specific light."""
    platform = getattr(hass.components, "test.light")
    platform.init()

    assert await async_setup_component(hass, light.DOMAIN,
                                       {light.DOMAIN: {
                                           CONF_PLATFORM: "test"
                                       }})
    await hass.async_block_till_done()

    mock_light_profiles["group.all_lights.default"] = color.color_xy_to_hs(
        0.3, 0.5) + (
            200,
            0,
        )
    mock_light_profiles["light.ceiling_2.default"] = color.color_xy_to_hs(
        0.6, 0.6) + (
            100,
            3,
        )

    dev = next(
        filter(lambda x: x.entity_id == "light.ceiling_2", platform.ENTITIES))
    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {
            ATTR_ENTITY_ID: dev.entity_id,
        },
        blocking=True,
    )

    _, data = dev.last_call("turn_on")
    assert data == {
        light.ATTR_HS_COLOR: (50.353, 100),
        light.ATTR_BRIGHTNESS: 100,
        light.ATTR_TRANSITION: 3,
    }
Ejemplo n.º 23
0
 async def _update_attrs(self):
     """Update Adaptive Values."""
     # Setting all values because this method takes <0.5ms to execute.
     self._percent = self._calc_percent()
     self._brightness = self._calc_brightness()
     self._color_temp_kelvin = self._calc_color_temp_kelvin()
     self._color_temp_mired = color_temperature_kelvin_to_mired(
         self._color_temp_kelvin)
     self._rgb_color = color_temperature_to_rgb(self._color_temp_kelvin)
     self._xy_color = color_RGB_to_xy(*self._rgb_color)
     self._hs_color = color_xy_to_hs(*self._xy_color)
     self.async_write_ha_state()
     _LOGGER.debug("'_update_attrs' called for %s", self._name)
Ejemplo n.º 24
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(hass, 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)
Ejemplo n.º 25
0
def test_hs_color():
    """Test hs_color property."""
    light = hue_light.HueLight(
        light=Mock(state={
            'colormode': 'ct',
            'hue': 1234,
            'sat': 123,
        },
                   raw=LIGHT_RAW,
                   colorgamuttype=LIGHT_GAMUT_TYPE,
                   colorgamut=LIGHT_GAMUT),
        request_bridge_update=None,
        bridge=Mock(),
        is_group=False,
    )

    assert light.hs_color is None

    light = hue_light.HueLight(
        light=Mock(state={
            'colormode': 'hs',
            'hue': 1234,
            'sat': 123,
        },
                   raw=LIGHT_RAW,
                   colorgamuttype=LIGHT_GAMUT_TYPE,
                   colorgamut=LIGHT_GAMUT),
        request_bridge_update=None,
        bridge=Mock(),
        is_group=False,
    )

    assert light.hs_color is None

    light = hue_light.HueLight(
        light=Mock(state={
            'colormode': 'xy',
            'hue': 1234,
            'sat': 123,
            'xy': [0.4, 0.5]
        },
                   raw=LIGHT_RAW,
                   colorgamuttype=LIGHT_GAMUT_TYPE,
                   colorgamut=LIGHT_GAMUT),
        request_bridge_update=None,
        bridge=Mock(),
        is_group=False,
    )

    assert light.hs_color == color.color_xy_to_hs(0.4, 0.5, LIGHT_GAMUT)
Ejemplo n.º 26
0
def test_hs_color():
    """Test hs_color property."""
    light = hue_light.HueLight(
        light=Mock(
            state={"colormode": "ct", "hue": 1234, "sat": 123},
            raw=LIGHT_RAW,
            colorgamuttype=LIGHT_GAMUT_TYPE,
            colorgamut=LIGHT_GAMUT,
        ),
        coordinator=Mock(last_update_success=True),
        bridge=Mock(),
        is_group=False,
        supported_features=hue_light.SUPPORT_HUE_EXTENDED,
        rooms={},
    )

    assert light.hs_color is None

    light = hue_light.HueLight(
        light=Mock(
            state={"colormode": "hs", "hue": 1234, "sat": 123},
            raw=LIGHT_RAW,
            colorgamuttype=LIGHT_GAMUT_TYPE,
            colorgamut=LIGHT_GAMUT,
        ),
        coordinator=Mock(last_update_success=True),
        bridge=Mock(),
        is_group=False,
        supported_features=hue_light.SUPPORT_HUE_EXTENDED,
        rooms={},
    )

    assert light.hs_color is None

    light = hue_light.HueLight(
        light=Mock(
            state={"colormode": "xy", "hue": 1234, "sat": 123, "xy": [0.4, 0.5]},
            raw=LIGHT_RAW,
            colorgamuttype=LIGHT_GAMUT_TYPE,
            colorgamut=LIGHT_GAMUT,
        ),
        coordinator=Mock(last_update_success=True),
        bridge=Mock(),
        is_group=False,
        supported_features=hue_light.SUPPORT_HUE_EXTENDED,
        rooms={},
    )

    assert light.hs_color == color.color_xy_to_hs(0.4, 0.5, LIGHT_GAMUT)
Ejemplo n.º 27
0
def test_color_xy_to_hs():
    """Test color_xy_to_hs."""
    assert color_util.color_xy_to_hs(1, 1) == (47.294, 100)

    assert color_util.color_xy_to_hs(0.35, 0.35) == (38.182, 12.941)

    assert color_util.color_xy_to_hs(1, 0) == (345.882, 100)

    assert color_util.color_xy_to_hs(0, 1) == (120, 100)

    assert color_util.color_xy_to_hs(0, 0) == (225.176, 100)

    assert color_util.color_xy_to_hs(1, 0, GAMUT) == (359.294, 100)

    assert color_util.color_xy_to_hs(0, 1, GAMUT) == (100.706, 100)

    assert color_util.color_xy_to_hs(0, 0, GAMUT) == (221.463, 96.471)
Ejemplo n.º 28
0
        def xy_received(msg):
            """Handle new MQTT messages for xy color."""
            payload = self._value_templates[CONF_XY_VALUE_TEMPLATE](msg.payload, None)
            if not payload:
                _LOGGER.debug("Ignoring empty xy-color message from '%s'", msg.topic)
                return

            xy_color = tuple(float(val) for val in payload.split(","))
            if self._optimistic_color_mode:
                self._color_mode = COLOR_MODE_XY
            if self._legacy_mode:
                self._hs_color = color_util.color_xy_to_hs(*xy_color)
            else:
                self._xy_color = xy_color
            self.async_write_ha_state()
Ejemplo n.º 29
0
    def _update(self, force_update=True):
        """Synchronize state with bridge."""
        self._update_lights(no_throttle=force_update)
        self._state = self.wemo.state

        self._is_on = self._state.get('onoff') != 0
        self._brightness = self._state.get('level', 255)
        self._color_temp = self._state.get('temperature_mireds')
        self._available = True

        xy_color = self._state.get('color_xy')

        if xy_color:
            self._hs_color = color_util.color_xy_to_hs(*xy_color)
        else:
            self._hs_color = None
Ejemplo n.º 30
0
    def _update(self, force_update=True):
        """Synchronize state with bridge."""
        with self._wemo_exception_handler("update status") as handler:
            self._update_lights(no_throttle=force_update)
            self._state = self.wemo.state
        if handler.success:
            self._is_on = self._state.get("onoff") != WEMO_OFF
            self._brightness = self._state.get("level", 255)
            self._color_temp = self._state.get("temperature_mireds")

            xy_color = self._state.get("color_xy")

            if xy_color:
                self._hs_color = color_util.color_xy_to_hs(*xy_color)
            else:
                self._hs_color = None
Ejemplo n.º 31
0
async def test_light_profiles(hass, mock_light_profiles):
    """Test light profiles."""
    platform = getattr(hass.components, "test.light")
    platform.init()

    mock_light_profiles["test"] = color.color_xy_to_hs(0.4, 0.6) + (100, 0)
    mock_light_profiles["test_off"] = 0, 0, 0, 0

    assert await async_setup_component(hass, light.DOMAIN,
                                       {light.DOMAIN: {
                                           CONF_PLATFORM: "test"
                                       }})
    await hass.async_block_till_done()

    ent1, _, _ = platform.ENTITIES

    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {
            ATTR_ENTITY_ID: ent1.entity_id,
            light.ATTR_PROFILE: "test",
        },
        blocking=True,
    )

    _, data = ent1.last_call("turn_on")
    assert light.is_on(hass, ent1.entity_id)
    assert data == {
        light.ATTR_HS_COLOR: (71.059, 100),
        light.ATTR_BRIGHTNESS: 100,
        light.ATTR_TRANSITION: 0,
    }

    await hass.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {
            ATTR_ENTITY_ID: ent1.entity_id,
            light.ATTR_PROFILE: "test_off"
        },
        blocking=True,
    )

    _, data = ent1.last_call("turn_off")
    assert not light.is_on(hass, ent1.entity_id)
    assert data == {light.ATTR_TRANSITION: 0}
Ejemplo n.º 32
0
    def find_hsbk(self, **kwargs):
        """Find the desired color from a number of possible inputs."""
        changed_color = False

        hsbk = kwargs.pop(ATTR_HSBK, None)
        if hsbk is not None:
            return [hsbk, True]

        preprocess_turn_on_alternatives(kwargs)

        if ATTR_RGB_COLOR in kwargs:
            hue, saturation, brightness = \
                color_util.color_RGB_to_hsv(*kwargs[ATTR_RGB_COLOR])
            saturation = convert_8_to_16(saturation)
            brightness = convert_8_to_16(brightness)
            changed_color = True
        else:
            hue = self._hue
            saturation = self._sat
            brightness = self._bri

        if ATTR_XY_COLOR in kwargs:
            hue, saturation = color_util.color_xy_to_hs(*kwargs[ATTR_XY_COLOR])
            saturation = convert_8_to_16(saturation)
            changed_color = True

        # When color or temperature is set, use a default value for the other
        if ATTR_COLOR_TEMP in kwargs:
            kelvin = int(color_util.color_temperature_mired_to_kelvin(
                kwargs[ATTR_COLOR_TEMP]))
            if not changed_color:
                saturation = 0
            changed_color = True
        else:
            if changed_color:
                kelvin = 3500
            else:
                kelvin = self._kel

        if ATTR_BRIGHTNESS in kwargs:
            brightness = convert_8_to_16(kwargs[ATTR_BRIGHTNESS])
            changed_color = True
        else:
            brightness = self._bri

        return [[hue, saturation, brightness, kelvin], changed_color]
Ejemplo n.º 33
0
    async def async_get_state(self, from_cache=True):
        """Attempt to retrieve on off state from the light."""
        if not from_cache and not self.available:
            return
        self.debug("polling current state - from cache: %s", from_cache)
        if self._on_off_channel:
            state = await self._on_off_channel.get_attribute_value(
                "on_off", from_cache=from_cache)
            if state is not None:
                self._state = state
        if self._level_channel:
            level = await self._level_channel.get_attribute_value(
                "current_level", from_cache=from_cache)
            if level is not None:
                self._brightness = level
        if self._color_channel:
            attributes = []
            color_capabilities = self._color_channel.get_color_capabilities()
            if (color_capabilities is not None
                    and color_capabilities & CAPABILITIES_COLOR_TEMP):
                attributes.append("color_temperature")
            if (color_capabilities is not None
                    and color_capabilities & CAPABILITIES_COLOR_XY):
                attributes.append("current_x")
                attributes.append("current_y")
            if (color_capabilities is not None
                    and color_capabilities & CAPABILITIES_COLOR_LOOP):
                attributes.append("color_loop_active")

            results = await self._color_channel.get_attributes(
                attributes, from_cache=from_cache)

            if ("color_temperature" in results
                    and results["color_temperature"] is not None):
                self._color_temp = results["color_temperature"]

            color_x = results.get("current_x")
            color_y = results.get("current_y")
            if color_x is not None and color_y is not None:
                self._hs_color = color_util.color_xy_to_hs(
                    float(color_x / 65535), float(color_y / 65535))
            if ("color_loop_active" in results
                    and results["color_loop_active"] is not None):
                color_loop_active = results["color_loop_active"]
                if color_loop_active == 1:
                    self._effect = light.EFFECT_COLORLOOP
Ejemplo n.º 34
0
    def state_attributes(self):
        """Return state attributes."""
        if not self.is_on:
            return None

        data = {}
        data[ATTR_BRIGHTNESS] = self.brightness
        data[ATTR_COLOR_TEMP] = self.color_temp
        data[ATTR_XY_COLOR] = (
            self._lamp_state.x_chromaticity,
            self._lamp_state.y_chromaticity,
        )
        data[ATTR_HS_COLOR] = color_util.color_xy_to_hs(*data[ATTR_XY_COLOR])
        data[ATTR_RGB_COLOR] = color_util.color_xy_to_RGB(*data[ATTR_XY_COLOR])
        data[ATTR_WHITE_VALUE] = self.white_value

        return {key: val for key, val in data.items() if val is not None}
Ejemplo n.º 35
0
    def find_hsbk(self, **kwargs):
        """Find the desired color from a number of possible inputs."""
        changed_color = False

        hsbk = kwargs.pop(ATTR_HSBK, None)
        if hsbk is not None:
            return [hsbk, True]

        color_name = kwargs.pop(ATTR_COLOR_NAME, None)
        if color_name is not None:
            kwargs[ATTR_RGB_COLOR] = color_util.color_name_to_rgb(color_name)

        if ATTR_RGB_COLOR in kwargs:
            hue, saturation, brightness = \
                convert_rgb_to_hsv(kwargs[ATTR_RGB_COLOR])
            changed_color = True
        else:
            hue = self._hue
            saturation = self._sat
            brightness = self._bri

        if ATTR_XY_COLOR in kwargs:
            hue, saturation = color_util.color_xy_to_hs(*kwargs[ATTR_XY_COLOR])
            saturation = saturation * (BYTE_MAX + 1)
            changed_color = True

        # When color or temperature is set, use a default value for the other
        if ATTR_COLOR_TEMP in kwargs:
            kelvin = int(color_temperature_mired_to_kelvin(
                kwargs[ATTR_COLOR_TEMP]))
            if not changed_color:
                saturation = 0
            changed_color = True
        else:
            if changed_color:
                kelvin = 3500
            else:
                kelvin = self._kel

        if ATTR_BRIGHTNESS in kwargs:
            brightness = kwargs[ATTR_BRIGHTNESS] * (BYTE_MAX + 1)
            changed_color = True
        else:
            brightness = self._bri

        return [[hue, saturation, brightness, kelvin], changed_color]
Ejemplo n.º 36
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)
     return data
Ejemplo n.º 37
0
 def _light_internal_convert_color(self,
                                   color_mode: ColorMode | str) -> dict:
     data: dict[str, tuple] = {}
     if color_mode == ColorMode.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 == ColorMode.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 == ColorMode.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 == ColorMode.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 == ColorMode.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)
     elif color_mode == ColorMode.COLOR_TEMP and self.color_temp:
         hs_color = color_util.color_temperature_to_hs(
             color_util.color_temperature_mired_to_kelvin(self.color_temp))
         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)
     return data
Ejemplo n.º 38
0
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:
        _LOGGER.debug(f"Turning on light with profile {profile}")
        profile_xy_color = profile[:2]
        if profile_xy_color[0] is not None and profile_xy_color[1] is not None:
            params.setdefault(ATTR_XY_COLOR, profile_xy_color)
        if profile[2] is not None:
            params.setdefault(ATTR_BRIGHTNESS, profile[2])
        if len(profile) > 3:
            params.setdefault(ATTR_TRANSITION, profile[3])

    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] = round(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)

    return params
Ejemplo n.º 39
0
    def hs_color(self):
        """Return the hs color value."""
        # pylint: disable=redefined-outer-name
        mode = self._color_mode

        if mode not in ('hs', 'xy'):
            return

        source = self.light.action if self.is_group else self.light.state

        hue = source.get('hue')
        sat = source.get('sat')

        # Sometimes the state will not include valid hue/sat values.
        # Reported as issue 13434
        if hue is not None and sat is not None:
            return hue / 65535 * 360, sat / 255 * 100

        if 'xy' not in source:
            return None

        return color.color_xy_to_hs(*source['xy'])
Ejemplo n.º 40
0
    def _update(self, force_update=True):
        """Synchronize state with bridge."""
        try:
            self._update_lights(no_throttle=force_update)
            self._state = self.wemo.state
        except (AttributeError, ActionException) as err:
            _LOGGER.warning("Could not update status for %s (%s)", self.name,
                            err)
            self._available = False
            self.wemo.bridge.reconnect_with_device()
        else:
            self._is_on = self._state.get("onoff") != WEMO_OFF
            self._brightness = self._state.get("level", 255)
            self._color_temp = self._state.get("temperature_mireds")
            self._available = True

            xy_color = self._state.get("color_xy")

            if xy_color:
                self._hs_color = color_util.color_xy_to_hs(*xy_color)
            else:
                self._hs_color = None
Ejemplo n.º 41
0
 def hs_color(self):
     """Return the hs color value."""
     if self._light.colormode in ('xy', 'hs') and self._light.xy:
         return color_util.color_xy_to_hs(*self._light.xy)
     return None
Ejemplo n.º 42
0
        def state_received(topic, payload, qos):
            """Handle new MQTT messages."""
            values = json.loads(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")

            if self._brightness is not None:
                try:
                    self._brightness = int(values['brightness'] /
                                           float(self._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_schedule_update_ha_state()
Ejemplo n.º 43
0
 def hs_color(self):
     """Define current bulb color."""
     if not self.wink.supports_xy_color():
         return None
     return color_util.color_xy_to_hs(*self.wink.color_xy())
Ejemplo n.º 44
0
        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.get(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_ha_state()
Ejemplo n.º 45
0
 def xy_received(topic, payload, qos):
     """Handle new MQTT messages for  color."""
     xy_color = [float(val) for val in
                 templates[CONF_XY](payload).split(',')]
     self._hs = color_util.color_xy_to_hs(*xy_color)
     self.async_schedule_update_ha_state()
Ejemplo n.º 46
0
 def hs_color(self):
     """Return the hs color values of this light."""
     xy_color = self.device.state.get('color_xy')
     return color_util.color_xy_to_hs(*xy_color) if xy_color else None