예제 #1
0
파일: light.py 프로젝트: OpenPeerPower/core
    def turn_on(self, **kwargs):
        """Turn the light on."""
        xy_color = None

        brightness = kwargs.get(ATTR_BRIGHTNESS, self.brightness or 255)
        color_temp = kwargs.get(ATTR_COLOR_TEMP)
        hs_color = kwargs.get(ATTR_HS_COLOR)
        transition_time = int(kwargs.get(ATTR_TRANSITION, 0))

        if hs_color is not None:
            xy_color = color_util.color_hs_to_xy(*hs_color)

        turn_on_kwargs = {
            "level": brightness,
            "transition": transition_time,
            "force_update": False,
        }

        with self._wemo_exception_handler("turn on"):
            if xy_color is not None:
                self.wemo.set_color(xy_color, transition=transition_time)

            if color_temp is not None:
                self.wemo.set_temperature(mireds=color_temp, transition=transition_time)

            if self.wemo.turn_on(**turn_on_kwargs):
                self._state["onoff"] = WEMO_ON

        self.schedule_update_op_state()
예제 #2
0
    def state_attributes(self):
        """Return state attributes."""
        if not self.is_on:
            return None

        data = {}
        supported_features = self.supported_features

        if supported_features & SUPPORT_BRIGHTNESS:
            data[ATTR_BRIGHTNESS] = self.brightness

        if supported_features & SUPPORT_COLOR_TEMP:
            data[ATTR_COLOR_TEMP] = self.color_temp

        if supported_features & SUPPORT_COLOR and self.hs_color:
            # pylint: disable=unsubscriptable-object,not-an-iterable
            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)

        if supported_features & SUPPORT_WHITE_VALUE:
            data[ATTR_WHITE_VALUE] = self.white_value

        if supported_features & SUPPORT_EFFECT:
            data[ATTR_EFFECT] = self.effect

        return {key: val for key, val in data.items() if val is not None}
예제 #3
0
파일: light.py 프로젝트: OpenPeerPower/core
    async def async_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_HS_COLOR in kwargs:
            if self.is_osram:
                command["hue"] = int(kwargs[ATTR_HS_COLOR][0] / 360 * 65535)
                command["sat"] = int(kwargs[ATTR_HS_COLOR][1] / 100 * 255)
            else:
                # Philips hue bulb models respond differently to hue/sat
                # requests, so we convert to XY first to ensure a consistent
                # color.
                xy_color = color.color_hs_to_xy(*kwargs[ATTR_HS_COLOR],
                                                self.gamut)
                command["xy"] = xy_color
        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"] = opp_to_hue_brightness(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 not self.is_innr:
            command["alert"] = "none"

        if ATTR_EFFECT in kwargs:
            effect = kwargs[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)
            else:
                command["effect"] = "none"

        if self.is_group:
            await self.bridge.async_request_call(
                partial(self.light.set_action, **command))
        else:
            await self.bridge.async_request_call(
                partial(self.light.set_state, **command))

        await self.coordinator.async_request_refresh()
예제 #4
0
def test_color_hs_to_xy():
    """Test color_hs_to_xy."""
    assert color_util.color_hs_to_xy(180, 100) == (0.151, 0.343)

    assert color_util.color_hs_to_xy(350, 12.5) == (0.356, 0.321)

    assert color_util.color_hs_to_xy(140, 50) == (0.229, 0.474)

    assert color_util.color_hs_to_xy(0, 40) == (0.474, 0.317)

    assert color_util.color_hs_to_xy(360, 0) == (0.323, 0.329)

    assert color_util.color_hs_to_xy(0, 100, GAMUT) == (0.7, 0.299)

    assert color_util.color_hs_to_xy(120, 100, GAMUT) == (0.215, 0.711)

    assert color_util.color_hs_to_xy(180, 100, GAMUT) == (0.17, 0.34)

    assert color_util.color_hs_to_xy(240, 100, GAMUT) == (0.138, 0.08)

    assert color_util.color_hs_to_xy(360, 100, GAMUT) == (0.7, 0.299)
예제 #5
0
    def turn_on(self, **kwargs):
        """Turn the switch on."""
        brightness = kwargs.get(ATTR_BRIGHTNESS)
        hs_color = kwargs.get(ATTR_HS_COLOR)
        color_temp_mired = kwargs.get(ATTR_COLOR_TEMP)

        state_kwargs = {}

        if hs_color:
            if self.wink.supports_xy_color():
                xy_color = color_util.color_hs_to_xy(*hs_color)
                state_kwargs["color_xy"] = xy_color
            if self.wink.supports_hue_saturation():
                hs_scaled = hs_color[0] / 360, hs_color[1] / 100
                state_kwargs["color_hue_saturation"] = hs_scaled

        if color_temp_mired:
            state_kwargs["color_kelvin"] = mired_to_kelvin(color_temp_mired)

        if brightness:
            state_kwargs["brightness"] = brightness / 255.0

        self.wink.set_state(True, **state_kwargs)
예제 #6
0
    async def async_turn_on(self, **kwargs):
        """Turn on light."""
        data = {"on": True}

        if ATTR_COLOR_TEMP in kwargs:
            data["ct"] = kwargs[ATTR_COLOR_TEMP]

        if ATTR_HS_COLOR in kwargs:
            if self._device.xy is not None:
                data["xy"] = color_util.color_hs_to_xy(*kwargs[ATTR_HS_COLOR])
            else:
                data["hue"] = int(kwargs[ATTR_HS_COLOR][0] / 360 * 65535)
                data["sat"] = int(kwargs[ATTR_HS_COLOR][1] / 100 * 255)

        if ATTR_BRIGHTNESS in kwargs:
            data["bri"] = kwargs[ATTR_BRIGHTNESS]

        if ATTR_TRANSITION in kwargs:
            data["transitiontime"] = int(kwargs[ATTR_TRANSITION] * 10)
        elif "IKEA" in self._device.manufacturer:
            data["transitiontime"] = 0

        if ATTR_FLASH in kwargs:
            if kwargs[ATTR_FLASH] == FLASH_SHORT:
                data["alert"] = "select"
                del data["on"]
            elif kwargs[ATTR_FLASH] == FLASH_LONG:
                data["alert"] = "lselect"
                del data["on"]

        if ATTR_EFFECT in kwargs:
            if kwargs[ATTR_EFFECT] == EFFECT_COLORLOOP:
                data["effect"] = "colorloop"
            else:
                data["effect"] = "none"

        await self._device.async_set_state(data)
예제 #7
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
예제 #8
0
파일: light.py 프로젝트: OpenPeerPower/core
    async def async_turn_on(self, **kwargs):
        """Turn the entity on."""
        transition = kwargs.get(light.ATTR_TRANSITION)
        duration = (
            transition * 10
            if transition
            else self._default_transition * 10
            if self._default_transition
            else DEFAULT_TRANSITION
        )
        brightness = kwargs.get(light.ATTR_BRIGHTNESS)
        effect = kwargs.get(light.ATTR_EFFECT)
        flash = kwargs.get(light.ATTR_FLASH)

        if brightness is None and self._off_brightness is not None:
            brightness = self._off_brightness

        t_log = {}
        if (
            brightness is not None or transition
        ) and self._supported_features & light.SUPPORT_BRIGHTNESS:
            if brightness is not None:
                level = min(254, brightness)
            else:
                level = self._brightness or 254
            result = await self._level_channel.move_to_level_with_on_off(
                level, duration
            )
            t_log["move_to_level_with_on_off"] = result
            if not isinstance(result, list) or result[1] is not Status.SUCCESS:
                self.debug("turned on: %s", t_log)
                return
            self._state = bool(level)
            if level:
                self._brightness = level

        if brightness is None or (self._FORCE_ON and brightness):
            # since some lights don't always turn on with move_to_level_with_on_off,
            # we should call the on command on the on_off cluster if brightness is not 0.
            result = await self._on_off_channel.on()
            t_log["on_off"] = result
            if not isinstance(result, list) or result[1] is not Status.SUCCESS:
                self.debug("turned on: %s", t_log)
                return
            self._state = True
        if (
            light.ATTR_COLOR_TEMP in kwargs
            and self.supported_features & light.SUPPORT_COLOR_TEMP
        ):
            temperature = kwargs[light.ATTR_COLOR_TEMP]
            result = await self._color_channel.move_to_color_temp(temperature, duration)
            t_log["move_to_color_temp"] = result
            if not isinstance(result, list) or result[1] is not Status.SUCCESS:
                self.debug("turned on: %s", t_log)
                return
            self._color_temp = temperature
            self._hs_color = None

        if (
            light.ATTR_HS_COLOR in kwargs
            and self.supported_features & light.SUPPORT_COLOR
        ):
            hs_color = kwargs[light.ATTR_HS_COLOR]
            xy_color = color_util.color_hs_to_xy(*hs_color)
            result = await self._color_channel.move_to_color(
                int(xy_color[0] * 65535), int(xy_color[1] * 65535), duration
            )
            t_log["move_to_color"] = result
            if not isinstance(result, list) or result[1] is not Status.SUCCESS:
                self.debug("turned on: %s", t_log)
                return
            self._hs_color = hs_color
            self._color_temp = None

        if (
            effect == light.EFFECT_COLORLOOP
            and self.supported_features & light.SUPPORT_EFFECT
        ):
            result = await self._color_channel.color_loop_set(
                UPDATE_COLORLOOP_ACTION
                | UPDATE_COLORLOOP_DIRECTION
                | UPDATE_COLORLOOP_TIME,
                0x2,  # start from current hue
                0x1,  # only support up
                transition if transition else 7,  # transition
                0,  # no hue
            )
            t_log["color_loop_set"] = result
            self._effect = light.EFFECT_COLORLOOP
        elif (
            self._effect == light.EFFECT_COLORLOOP
            and effect != light.EFFECT_COLORLOOP
            and self.supported_features & light.SUPPORT_EFFECT
        ):
            result = await self._color_channel.color_loop_set(
                UPDATE_COLORLOOP_ACTION,
                0x0,
                0x0,
                0x0,
                0x0,  # update action only, action off, no dir, time, hue
            )
            t_log["color_loop_set"] = result
            self._effect = None

        if flash is not None and self._supported_features & light.SUPPORT_FLASH:
            result = await self._identify_channel.trigger_effect(
                FLASH_EFFECTS[flash], EFFECT_DEFAULT_VARIANT
            )
            t_log["trigger_effect"] = result

        self._off_brightness = None
        self.debug("turned on: %s", t_log)
        self.async_write_op_state()
예제 #9
0
    async def async_turn_on(self, **kwargs):
        """Turn the device on.

        This method is a coroutine.
        """
        should_update = False

        message = {"state": "ON"}

        if ATTR_HS_COLOR in kwargs and (self._config[CONF_HS]
                                        or self._config[CONF_RGB]
                                        or self._config[CONF_XY]):
            hs_color = kwargs[ATTR_HS_COLOR]
            message["color"] = {}
            if self._config[CONF_RGB]:
                # If there's a brightness topic set, we don't want to scale the
                # RGB values given using the brightness.
                if self._brightness is not None:
                    brightness = 255
                else:
                    brightness = kwargs.get(
                        ATTR_BRIGHTNESS,
                        self._brightness if self._brightness else 255)
                rgb = color_util.color_hsv_to_RGB(hs_color[0], hs_color[1],
                                                  brightness / 255 * 100)
                message["color"]["r"] = rgb[0]
                message["color"]["g"] = rgb[1]
                message["color"]["b"] = rgb[2]
            if self._config[CONF_XY]:
                xy_color = color_util.color_hs_to_xy(*kwargs[ATTR_HS_COLOR])
                message["color"]["x"] = xy_color[0]
                message["color"]["y"] = xy_color[1]
            if self._config[CONF_HS]:
                message["color"]["h"] = hs_color[0]
                message["color"]["s"] = hs_color[1]

            if self._optimistic:
                self._hs = kwargs[ATTR_HS_COLOR]
                should_update = True

        if ATTR_FLASH in kwargs:
            flash = kwargs.get(ATTR_FLASH)

            if flash == FLASH_LONG:
                message["flash"] = self._flash_times[CONF_FLASH_TIME_LONG]
            elif flash == FLASH_SHORT:
                message["flash"] = self._flash_times[CONF_FLASH_TIME_SHORT]

        if ATTR_TRANSITION in kwargs:
            message["transition"] = kwargs[ATTR_TRANSITION]

        if ATTR_BRIGHTNESS in kwargs and self._brightness is not None:
            message["brightness"] = int(kwargs[ATTR_BRIGHTNESS] /
                                        float(DEFAULT_BRIGHTNESS_SCALE) *
                                        self._config[CONF_BRIGHTNESS_SCALE])

            if self._optimistic:
                self._brightness = kwargs[ATTR_BRIGHTNESS]
                should_update = True

        if ATTR_COLOR_TEMP in kwargs:
            message["color_temp"] = int(kwargs[ATTR_COLOR_TEMP])

            if self._optimistic:
                self._color_temp = kwargs[ATTR_COLOR_TEMP]
                should_update = True

        if ATTR_EFFECT in kwargs:
            message["effect"] = kwargs[ATTR_EFFECT]

            if self._optimistic:
                self._effect = kwargs[ATTR_EFFECT]
                should_update = True

        if ATTR_WHITE_VALUE in kwargs:
            message["white_value"] = int(kwargs[ATTR_WHITE_VALUE])

            if self._optimistic:
                self._white_value = kwargs[ATTR_WHITE_VALUE]
                should_update = True

        mqtt.async_publish(
            self.opp,
            self._topic[CONF_COMMAND_TOPIC],
            json.dumps(message),
            self._config[CONF_QOS],
            self._config[CONF_RETAIN],
        )

        if self._optimistic:
            # Optimistically assume that the light has changed state.
            self._state = True
            should_update = True

        if should_update:
            self.async_write_op_state()
예제 #10
0
    async def async_turn_on(self, **kwargs):  # noqa: C901
        """Turn the device on.

        This method is a coroutine.
        """
        should_update = False

        message = {"state": "ON"}

        if ATTR_HS_COLOR in kwargs and (
            self._config[CONF_HS] or self._config[CONF_RGB] or self._config[CONF_XY]
        ):
            hs_color = kwargs[ATTR_HS_COLOR]
            message["color"] = {}
            if self._config[CONF_RGB]:
                # If there's a brightness topic set, we don't want to scale the
                # RGB values given using the brightness.
                if self._config[CONF_BRIGHTNESS]:
                    brightness = 255
                else:
                    brightness = kwargs.get(ATTR_BRIGHTNESS, 255)
                rgb = color_util.color_hsv_to_RGB(
                    hs_color[0], hs_color[1], brightness / 255 * 100
                )
                message["color"]["r"] = rgb[0]
                message["color"]["g"] = rgb[1]
                message["color"]["b"] = rgb[2]
            if self._config[CONF_XY]:
                xy_color = color_util.color_hs_to_xy(*kwargs[ATTR_HS_COLOR])
                message["color"]["x"] = xy_color[0]
                message["color"]["y"] = xy_color[1]
            if self._config[CONF_HS]:
                message["color"]["h"] = hs_color[0]
                message["color"]["s"] = hs_color[1]

            if self._optimistic:
                self._hs = kwargs[ATTR_HS_COLOR]
                should_update = True

        if ATTR_HS_COLOR in kwargs and self._supports_color_mode(COLOR_MODE_HS):
            hs_color = kwargs[ATTR_HS_COLOR]
            message["color"] = {"h": hs_color[0], "s": hs_color[1]}
            if self._optimistic:
                self._color_mode = COLOR_MODE_HS
                self._hs = hs_color
                should_update = True

        if ATTR_RGB_COLOR in kwargs and self._supports_color_mode(COLOR_MODE_RGB):
            rgb = self._scale_rgbxx(kwargs[ATTR_RGB_COLOR], kwargs)
            message["color"] = {"r": rgb[0], "g": rgb[1], "b": rgb[2]}
            if self._optimistic:
                self._color_mode = COLOR_MODE_RGB
                self._rgb = rgb
                should_update = True

        if ATTR_RGBW_COLOR in kwargs and self._supports_color_mode(COLOR_MODE_RGBW):
            rgb = self._scale_rgbxx(kwargs[ATTR_RGBW_COLOR], kwargs)
            message["color"] = {"r": rgb[0], "g": rgb[1], "b": rgb[2], "w": rgb[3]}
            if self._optimistic:
                self._color_mode = COLOR_MODE_RGBW
                self._rgbw = rgb
                should_update = True

        if ATTR_RGBWW_COLOR in kwargs and self._supports_color_mode(COLOR_MODE_RGBWW):
            rgb = self._scale_rgbxx(kwargs[ATTR_RGBWW_COLOR], kwargs)
            message["color"] = {
                "r": rgb[0],
                "g": rgb[1],
                "b": rgb[2],
                "c": rgb[3],
                "w": rgb[4],
            }
            if self._optimistic:
                self._color_mode = COLOR_MODE_RGBWW
                self._rgbww = rgb
                should_update = True

        if ATTR_XY_COLOR in kwargs and self._supports_color_mode(COLOR_MODE_XY):
            xy = kwargs[ATTR_XY_COLOR]  # pylint: disable=invalid-name
            message["color"] = {"x": xy[0], "y": xy[1]}
            if self._optimistic:
                self._color_mode = COLOR_MODE_XY
                self._xy = xy
                should_update = True

        self._set_flash_and_transition(message, **kwargs)

        if ATTR_BRIGHTNESS in kwargs and self._config[CONF_BRIGHTNESS]:
            brightness_normalized = kwargs[ATTR_BRIGHTNESS] / DEFAULT_BRIGHTNESS_SCALE
            brightness_scale = self._config[CONF_BRIGHTNESS_SCALE]
            device_brightness = min(
                round(brightness_normalized * brightness_scale), brightness_scale
            )
            # Make sure the brightness is not rounded down to 0
            device_brightness = max(device_brightness, 1)
            message["brightness"] = device_brightness

            if self._optimistic:
                self._brightness = kwargs[ATTR_BRIGHTNESS]
                should_update = True

        if ATTR_COLOR_TEMP in kwargs:
            message["color_temp"] = int(kwargs[ATTR_COLOR_TEMP])

            if self._optimistic:
                self._color_temp = kwargs[ATTR_COLOR_TEMP]
                should_update = True

        if ATTR_EFFECT in kwargs:
            message["effect"] = kwargs[ATTR_EFFECT]

            if self._optimistic:
                self._effect = kwargs[ATTR_EFFECT]
                should_update = True

        if ATTR_WHITE_VALUE in kwargs:
            message["white_value"] = int(kwargs[ATTR_WHITE_VALUE])

            if self._optimistic:
                self._white_value = kwargs[ATTR_WHITE_VALUE]
                should_update = True

        mqtt.async_publish(
            self.opp,
            self._topic[CONF_COMMAND_TOPIC],
            json.dumps(message),
            self._config[CONF_QOS],
            self._config[CONF_RETAIN],
        )

        if self._optimistic:
            # Optimistically assume that the light has changed state.
            self._state = True
            should_update = True

        if should_update:
            self.async_write_op_state()
예제 #11
0
async def test_device_types(opp: OpenPeerPower):
    """Test different device types."""
    mocked_bulb = _mocked_bulb()
    properties = {**PROPERTIES}
    properties.pop("active_mode")
    properties["color_mode"] = "3"
    mocked_bulb.last_properties = properties

    async def _async_setup(config_entry):
        with patch(f"{MODULE}.Bulb", return_value=mocked_bulb):
            await opp.config_entries.async_setup(config_entry.entry_id)
            await opp.async_block_till_done()

    async def _async_test(
        bulb_type,
        model,
        target_properties,
        nightlight_properties=None,
        name=UNIQUE_NAME,
        entity_id=ENTITY_LIGHT,
    ):
        config_entry = MockConfigEntry(
            domain=DOMAIN,
            data={
                **CONFIG_ENTRY_DATA,
                CONF_NIGHTLIGHT_SWITCH: False,
            },
        )
        config_entry.add_to_opp(opp)

        mocked_bulb.bulb_type = bulb_type
        model_specs = _MODEL_SPECS.get(model)
        type(mocked_bulb).get_model_specs = MagicMock(return_value=model_specs)
        await _async_setup(config_entry)

        state = opp.states.get(entity_id)
        assert state.state == "on"
        target_properties["friendly_name"] = name
        target_properties["flowing"] = False
        target_properties["night_light"] = True
        target_properties["music_mode"] = False
        assert dict(state.attributes) == target_properties

        await opp.config_entries.async_unload(config_entry.entry_id)
        await config_entry.async_remove(opp)
        registry = er.async_get(opp)
        registry.async_clear_config_entry(config_entry.entry_id)

        # nightlight
        if nightlight_properties is None:
            return
        config_entry = MockConfigEntry(
            domain=DOMAIN,
            data={
                **CONFIG_ENTRY_DATA,
                CONF_NIGHTLIGHT_SWITCH: True,
            },
        )
        config_entry.add_to_opp(opp)
        await _async_setup(config_entry)

        assert opp.states.get(entity_id).state == "off"
        state = opp.states.get(f"{entity_id}_nightlight")
        assert state.state == "on"
        nightlight_properties["friendly_name"] = f"{name} nightlight"
        nightlight_properties["icon"] = "mdi:weather-night"
        nightlight_properties["flowing"] = False
        nightlight_properties["night_light"] = True
        nightlight_properties["music_mode"] = False
        assert dict(state.attributes) == nightlight_properties

        await opp.config_entries.async_unload(config_entry.entry_id)
        await config_entry.async_remove(opp)
        registry.async_clear_config_entry(config_entry.entry_id)

    bright = round(255 * int(PROPERTIES["bright"]) / 100)
    current_brightness = round(255 * int(PROPERTIES["current_brightness"]) /
                               100)
    ct = color_temperature_kelvin_to_mired(int(PROPERTIES["ct"]))
    hue = int(PROPERTIES["hue"])
    sat = int(PROPERTIES["sat"])
    hs_color = (round(hue / 360 * 65536, 3), round(sat / 100 * 255, 3))
    rgb_color = color_hs_to_RGB(*hs_color)
    xy_color = color_hs_to_xy(*hs_color)
    bg_bright = round(255 * int(PROPERTIES["bg_bright"]) / 100)
    bg_ct = color_temperature_kelvin_to_mired(int(PROPERTIES["bg_ct"]))
    bg_rgb = int(PROPERTIES["bg_rgb"])
    bg_rgb_color = ((bg_rgb >> 16) & 0xFF, (bg_rgb >> 8) & 0xFF, bg_rgb & 0xFF)
    bg_hs_color = color_RGB_to_hs(*bg_rgb_color)
    bg_xy_color = color_RGB_to_xy(*bg_rgb_color)
    nl_br = round(255 * int(PROPERTIES["nl_br"]) / 100)

    # Default
    await _async_test(
        None,
        "mono",
        {
            "effect_list": YEELIGHT_MONO_EFFECT_LIST,
            "supported_features": SUPPORT_YEELIGHT,
            "brightness": bright,
            "color_mode": "brightness",
            "supported_color_modes": ["brightness"],
        },
    )

    # White
    await _async_test(
        BulbType.White,
        "mono",
        {
            "effect_list": YEELIGHT_MONO_EFFECT_LIST,
            "supported_features": SUPPORT_YEELIGHT,
            "brightness": bright,
            "color_mode": "brightness",
            "supported_color_modes": ["brightness"],
        },
    )

    # Color
    model_specs = _MODEL_SPECS["color"]
    await _async_test(
        BulbType.Color,
        "color",
        {
            "effect_list":
            YEELIGHT_COLOR_EFFECT_LIST,
            "supported_features":
            SUPPORT_YEELIGHT_RGB,
            "min_mireds":
            color_temperature_kelvin_to_mired(
                model_specs["color_temp"]["max"]),
            "max_mireds":
            color_temperature_kelvin_to_mired(
                model_specs["color_temp"]["min"]),
            "brightness":
            current_brightness,
            "color_temp":
            ct,
            "hs_color":
            hs_color,
            "rgb_color":
            rgb_color,
            "xy_color":
            xy_color,
            "color_mode":
            "hs",
            "supported_color_modes": ["color_temp", "hs"],
        },
        {
            "supported_features": 0,
            "color_mode": "onoff",
            "supported_color_modes": ["onoff"],
        },
    )

    # WhiteTemp
    model_specs = _MODEL_SPECS["ceiling1"]
    await _async_test(
        BulbType.WhiteTemp,
        "ceiling1",
        {
            "effect_list":
            YEELIGHT_TEMP_ONLY_EFFECT_LIST,
            "supported_features":
            SUPPORT_YEELIGHT_WHITE_TEMP,
            "min_mireds":
            color_temperature_kelvin_to_mired(
                model_specs["color_temp"]["max"]),
            "max_mireds":
            color_temperature_kelvin_to_mired(
                model_specs["color_temp"]["min"]),
            "brightness":
            current_brightness,
            "color_temp":
            ct,
            "color_mode":
            "color_temp",
            "supported_color_modes": ["color_temp"],
        },
        {
            "effect_list": YEELIGHT_TEMP_ONLY_EFFECT_LIST,
            "supported_features": SUPPORT_YEELIGHT,
            "brightness": nl_br,
            "color_mode": "brightness",
            "supported_color_modes": ["brightness"],
        },
    )

    # WhiteTempMood
    properties.pop("power")
    properties["main_power"] = "on"
    model_specs = _MODEL_SPECS["ceiling4"]
    await _async_test(
        BulbType.WhiteTempMood,
        "ceiling4",
        {
            "friendly_name":
            NAME,
            "effect_list":
            YEELIGHT_TEMP_ONLY_EFFECT_LIST,
            "flowing":
            False,
            "night_light":
            True,
            "supported_features":
            SUPPORT_YEELIGHT_WHITE_TEMP,
            "min_mireds":
            color_temperature_kelvin_to_mired(
                model_specs["color_temp"]["max"]),
            "max_mireds":
            color_temperature_kelvin_to_mired(
                model_specs["color_temp"]["min"]),
            "brightness":
            current_brightness,
            "color_temp":
            ct,
            "color_mode":
            "color_temp",
            "supported_color_modes": ["color_temp"],
        },
        {
            "effect_list": YEELIGHT_TEMP_ONLY_EFFECT_LIST,
            "supported_features": SUPPORT_YEELIGHT,
            "brightness": nl_br,
            "color_mode": "brightness",
            "supported_color_modes": ["brightness"],
        },
    )
    await _async_test(
        BulbType.WhiteTempMood,
        "ceiling4",
        {
            "effect_list": YEELIGHT_COLOR_EFFECT_LIST,
            "supported_features": SUPPORT_YEELIGHT_RGB,
            "min_mireds": color_temperature_kelvin_to_mired(6500),
            "max_mireds": color_temperature_kelvin_to_mired(1700),
            "brightness": bg_bright,
            "color_temp": bg_ct,
            "hs_color": bg_hs_color,
            "rgb_color": bg_rgb_color,
            "xy_color": bg_xy_color,
            "color_mode": "hs",
            "supported_color_modes": ["color_temp", "hs"],
        },
        name=f"{UNIQUE_NAME} ambilight",
        entity_id=f"{ENTITY_LIGHT}_ambilight",
    )
예제 #12
0
     elif (xy_color := params.pop(ATTR_XY_COLOR, None)) is not None:
         params[ATTR_HS_COLOR] = color_util.color_xy_to_hs(*xy_color)
 elif ATTR_HS_COLOR in params and COLOR_MODE_HS not in supported_color_modes:
     hs_color = params.pop(ATTR_HS_COLOR)
     if COLOR_MODE_RGB in supported_color_modes:
         params[ATTR_RGB_COLOR] = color_util.color_hs_to_RGB(*hs_color)
     elif COLOR_MODE_RGBW in supported_color_modes:
         rgb_color = color_util.color_hs_to_RGB(*hs_color)
         params[ATTR_RGBW_COLOR] = color_util.color_rgb_to_rgbw(
             *rgb_color)
     elif COLOR_MODE_RGBWW in supported_color_modes:
         rgb_color = color_util.color_hs_to_RGB(*hs_color)
         params[ATTR_RGBWW_COLOR] = color_util.color_rgb_to_rgbww(
             *rgb_color, light.min_mireds, light.max_mireds)
     elif COLOR_MODE_XY in supported_color_modes:
         params[ATTR_XY_COLOR] = color_util.color_hs_to_xy(*hs_color)
 elif ATTR_RGB_COLOR in params and COLOR_MODE_RGB not in supported_color_modes:
     rgb_color = params.pop(ATTR_RGB_COLOR)
     if COLOR_MODE_RGBW in supported_color_modes:
         params[ATTR_RGBW_COLOR] = color_util.color_rgb_to_rgbw(
             *rgb_color)
     elif COLOR_MODE_RGBWW in supported_color_modes:
         params[ATTR_RGBWW_COLOR] = color_util.color_rgb_to_rgbww(
             *rgb_color, light.min_mireds, light.max_mireds)
     elif COLOR_MODE_HS in supported_color_modes:
         params[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color)
     elif COLOR_MODE_XY in supported_color_modes:
         params[ATTR_XY_COLOR] = color_util.color_RGB_to_xy(*rgb_color)
 elif ATTR_XY_COLOR in params and COLOR_MODE_XY not in supported_color_modes:
     xy_color = params.pop(ATTR_XY_COLOR)
     if COLOR_MODE_HS in supported_color_modes: