コード例 #1
0
ファイル: light.py プロジェクト: OpenPeerPower/core
 def limitlessled_temperature(self):
     """Convert Open Peer Power color temperature units to percentage."""
     max_kelvin = color_temperature_mired_to_kelvin(self.min_mireds)
     min_kelvin = color_temperature_mired_to_kelvin(self.max_mireds)
     width = max_kelvin - min_kelvin
     kelvin = color_temperature_mired_to_kelvin(self._temperature)
     temperature = (kelvin - min_kelvin) / width
     return max(0, min(1, temperature))
コード例 #2
0
ファイル: light.py プロジェクト: OpenPeerPower/core
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
コード例 #3
0
ファイル: light.py プロジェクト: OpenPeerPower/core
    def turn_on(self, **kwargs):
        """Turn the light on."""
        if not self.is_on:
            self._lamp.switch(True)
        if ATTR_BRIGHTNESS in kwargs:
            brightness = int((kwargs[ATTR_BRIGHTNESS] / 255.0) * 200.0)
            self._lamp.brightness(brightness)
            return

        if ATTR_HS_COLOR in kwargs:
            rgb = color_util.color_hs_to_RGB(*kwargs[ATTR_HS_COLOR])
            self._lamp.rgb(*rgb)
            return

        if ATTR_COLOR_TEMP in kwargs:
            kelvin = int(
                color_util.color_temperature_mired_to_kelvin(
                    kwargs[ATTR_COLOR_TEMP]))
            self._lamp.white(kelvin)
            return

        if ATTR_EFFECT in kwargs:
            effect = kwargs[ATTR_EFFECT]
            self._lamp.effect(effect)
            return
コード例 #4
0
ファイル: type_lights.py プロジェクト: OpenPeerPower/core
    def async_update_state(self, new_state):
        """Update light after state change."""
        # Handle State
        state = new_state.state
        if state == STATE_ON and self.char_on.value != 1:
            self.char_on.set_value(1)
        elif state == STATE_OFF and self.char_on.value != 0:
            self.char_on.set_value(0)

        # Handle Brightness
        if CHAR_BRIGHTNESS in self.chars:
            brightness = new_state.attributes.get(ATTR_BRIGHTNESS)
            if isinstance(brightness, (int, float)):
                brightness = round(brightness / 255 * 100, 0)
                # The openpeerpower component might report its brightness as 0 but is
                # not off. But 0 is a special value in homekit. When you turn on a
                # homekit accessory it will try to restore the last brightness state
                # which will be the last value saved by char_brightness.set_value.
                # But if it is set to 0, HomeKit will update the brightness to 100 as
                # it thinks 0 is off.
                #
                # Therefore, if the the brightness is 0 and the device is still on,
                # the brightness is mapped to 1 otherwise the update is ignored in
                # order to avoid this incorrect behavior.
                if brightness == 0 and state == STATE_ON:
                    brightness = 1
                if self.char_brightness.value != brightness:
                    self.char_brightness.set_value(brightness)

        # Handle color temperature
        if CHAR_COLOR_TEMPERATURE in self.chars:
            color_temperature = new_state.attributes.get(ATTR_COLOR_TEMP)
            if isinstance(color_temperature, (int, float)):
                color_temperature = round(color_temperature, 0)
                if self.char_color_temperature.value != color_temperature:
                    self.char_color_temperature.set_value(color_temperature)

        # Handle Color
        if CHAR_SATURATION in self.chars and CHAR_HUE in self.chars:
            if ATTR_HS_COLOR in new_state.attributes:
                hue, saturation = new_state.attributes[ATTR_HS_COLOR]
            elif ATTR_COLOR_TEMP in new_state.attributes:
                hue, saturation = color_temperature_to_hs(
                    color_temperature_mired_to_kelvin(
                        new_state.attributes[ATTR_COLOR_TEMP]
                    )
                )
            else:
                hue, saturation = None, None
            if isinstance(hue, (int, float)) and isinstance(saturation, (int, float)):
                hue = round(hue, 0)
                saturation = round(saturation, 0)
                if hue != self.char_hue.value:
                    self.char_hue.set_value(hue)
                if saturation != self.char_saturation.value:
                    self.char_saturation.set_value(saturation)
コード例 #5
0
 def turn_on(self, **kwargs):
     """Turn on or control the light."""
     if (ATTR_BRIGHTNESS not in kwargs and ATTR_HS_COLOR not in kwargs
             and ATTR_COLOR_TEMP not in kwargs):
         self._tuya.turn_on()
     if ATTR_BRIGHTNESS in kwargs:
         self._tuya.set_brightness(kwargs[ATTR_BRIGHTNESS])
     if ATTR_HS_COLOR in kwargs:
         self._tuya.set_color(kwargs[ATTR_HS_COLOR])
     if ATTR_COLOR_TEMP in kwargs:
         color_temp = colorutil.color_temperature_mired_to_kelvin(
             kwargs[ATTR_COLOR_TEMP])
         self._tuya.set_color_temp(color_temp)
コード例 #6
0
ファイル: light.py プロジェクト: OpenPeerPower/core
    def turn_on(self, **kwargs):
        """Turn on the light."""
        if ATTR_COLOR_TEMP in kwargs and self._device.is_color_capable:
            self._device.set_color_temp(
                int(color_temperature_mired_to_kelvin(
                    kwargs[ATTR_COLOR_TEMP])))
            return

        if ATTR_HS_COLOR in kwargs and self._device.is_color_capable:
            self._device.set_color(kwargs[ATTR_HS_COLOR])
            return

        if ATTR_BRIGHTNESS in kwargs and self._device.is_dimmable:
            # Convert Open Peer Power brightness (0-255) to Abode brightness (0-99)
            # If 100 is sent to Abode, response is 99 causing an error
            self._device.set_level(ceil(kwargs[ATTR_BRIGHTNESS] * 99 / 255.0))
            return

        self._device.switch_on()
コード例 #7
0
ファイル: light.py プロジェクト: OpenPeerPower/core
    def turn_on(self, **kwargs):
        """Turn the device on."""
        transition = int(kwargs.get(ATTR_TRANSITION, 0) * 10)
        if ATTR_EFFECT in kwargs:
            self.play_effect(kwargs[ATTR_EFFECT], transition)
            return

        if ATTR_HS_COLOR in kwargs:
            self._rgb_color = color_util.color_hs_to_RGB(*kwargs[ATTR_HS_COLOR])
            self._luminary.set_rgb(*self._rgb_color, transition)

        if ATTR_COLOR_TEMP in kwargs:
            self._color_temp = kwargs[ATTR_COLOR_TEMP]
            self._luminary.set_temperature(
                int(color_util.color_temperature_mired_to_kelvin(self._color_temp)),
                transition,
            )

        self._is_on = True
        if ATTR_BRIGHTNESS in kwargs:
            self._brightness = kwargs[ATTR_BRIGHTNESS]
            self._luminary.set_luminance(int(self._brightness / 2.55), transition)
        else:
            self._luminary.set_onoff(True)
コード例 #8
0
def ct_to_hs(temp):
    """Convert color temperature (mireds) to hs."""
    colorlist = list(
        color_util.color_temperature_to_hs(
            color_util.color_temperature_mired_to_kelvin(temp)))
    return [int(val) for val in colorlist]
コード例 #9
0
ファイル: light.py プロジェクト: OpenPeerPower/core
    async def async_turn_on(self, **kwargs) -> None:
        """Turn on light."""
        if self.block.type == "relay":
            self.control_result = await self.set_state(turn="on")
            self.async_write_op_state()
            return

        set_mode = None
        supported_color_modes = self._supported_color_modes
        params: dict[str, Any] = {"turn": "on"}

        if ATTR_BRIGHTNESS in kwargs and brightness_supported(
                supported_color_modes):
            brightness_pct = int(100 * (kwargs[ATTR_BRIGHTNESS] + 1) / 255)
            if hasattr(self.block, "gain"):
                params["gain"] = brightness_pct
            if hasattr(self.block, "brightness"):
                params["brightness"] = brightness_pct

        if ATTR_COLOR_TEMP in kwargs and COLOR_MODE_COLOR_TEMP in supported_color_modes:
            color_temp = color_temperature_mired_to_kelvin(
                kwargs[ATTR_COLOR_TEMP])
            color_temp = min(self._max_kelvin, max(self._min_kelvin,
                                                   color_temp))
            # Color temperature change - used only in white mode, switch device mode to white
            set_mode = "white"
            params["temp"] = int(color_temp)

        if ATTR_RGB_COLOR in kwargs and COLOR_MODE_RGB in supported_color_modes:
            # Color channels change - used only in color mode, switch device mode to color
            set_mode = "color"
            (params["red"], params["green"],
             params["blue"]) = kwargs[ATTR_RGB_COLOR]

        if ATTR_RGBW_COLOR in kwargs and COLOR_MODE_RGBW in supported_color_modes:
            # Color channels change - used only in color mode, switch device mode to color
            set_mode = "color"
            (params["red"], params["green"], params["blue"],
             params["white"]) = kwargs[ATTR_RGBW_COLOR]

        if ATTR_EFFECT in kwargs:
            # Color effect change - used only in color mode, switch device mode to color
            set_mode = "color"
            if self.wrapper.model == "SHBLB-1":
                effect_dict = SHBLB_1_RGB_EFFECTS
            else:
                effect_dict = STANDARD_RGB_EFFECTS
            if kwargs[ATTR_EFFECT] in effect_dict.values():
                params["effect"] = [
                    k for k, v in effect_dict.items()
                    if v == kwargs[ATTR_EFFECT]
                ][0]
            else:
                _LOGGER.error(
                    "Effect '%s' not supported by device %s",
                    kwargs[ATTR_EFFECT],
                    self.wrapper.model,
                )

        if await self.set_light_mode(set_mode):
            self.control_result = await self.set_state(**params)

        self.async_write_op_state()
コード例 #10
0
def test_color_temperature_mired_to_kelvin():
    """Test color_temperature_mired_to_kelvin."""
    assert color_util.color_temperature_mired_to_kelvin(40) == 25000
    assert color_util.color_temperature_mired_to_kelvin(200) == 5000
    with pytest.raises(ZeroDivisionError):
        assert color_util.color_temperature_mired_to_kelvin(0)
コード例 #11
0
    async def async_turn_on(self, **kwargs):
        """Forward the turn_on command to all lights in the light group."""
        data = {ATTR_ENTITY_ID: self._entity_ids}
        emulate_color_temp_entity_ids = []

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

        if ATTR_HS_COLOR in kwargs:
            data[ATTR_HS_COLOR] = kwargs[ATTR_HS_COLOR]

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

            # Create a new entity list to mutate
            updated_entities = list(self._entity_ids)

            # Walk through initial entity ids, split entity lists by support
            for entity_id in self._entity_ids:
                state = self.opp.states.get(entity_id)
                if not state:
                    continue
                support = state.attributes.get(ATTR_SUPPORTED_FEATURES)
                # Only pass color temperature to supported entity_ids
                if bool(support & SUPPORT_COLOR) and not bool(
                    support & SUPPORT_COLOR_TEMP
                ):
                    emulate_color_temp_entity_ids.append(entity_id)
                    updated_entities.remove(entity_id)
                    data[ATTR_ENTITY_ID] = updated_entities

        if ATTR_WHITE_VALUE in kwargs:
            data[ATTR_WHITE_VALUE] = kwargs[ATTR_WHITE_VALUE]

        if ATTR_EFFECT in kwargs:
            data[ATTR_EFFECT] = kwargs[ATTR_EFFECT]

        if ATTR_TRANSITION in kwargs:
            data[ATTR_TRANSITION] = kwargs[ATTR_TRANSITION]

        if ATTR_FLASH in kwargs:
            data[ATTR_FLASH] = kwargs[ATTR_FLASH]

        if not emulate_color_temp_entity_ids:
            await self.opp.services.async_call(
                light.DOMAIN, light.SERVICE_TURN_ON, data, blocking=True
            )
            return

        emulate_color_temp_data = data.copy()
        temp_k = color_util.color_temperature_mired_to_kelvin(
            emulate_color_temp_data[ATTR_COLOR_TEMP]
        )
        hs_color = color_util.color_temperature_to_hs(temp_k)
        emulate_color_temp_data[ATTR_HS_COLOR] = hs_color
        del emulate_color_temp_data[ATTR_COLOR_TEMP]

        emulate_color_temp_data[ATTR_ENTITY_ID] = emulate_color_temp_entity_ids

        await asyncio.gather(
            self.opp.services.async_call(
                light.DOMAIN, light.SERVICE_TURN_ON, data, blocking=True
            ),
            self.opp.services.async_call(
                light.DOMAIN,
                light.SERVICE_TURN_ON,
                emulate_color_temp_data,
                blocking=True,
            ),
        )
コード例 #12
0
 async def async_set_color_temp(self, value: float):
     """Set the color temperature of the device."""
     kelvin = color_util.color_temperature_mired_to_kelvin(value)
     kelvin = max(min(kelvin, 30000.0), 1.0)
     await self._device.set_color_temperature(kelvin, set_status=True)
コード例 #13
0
ファイル: light.py プロジェクト: OpenPeerPower/core
    async def async_turn_on(self, **kwargs):
        """Instruct the light to turn on."""
        transition_time = None
        if ATTR_TRANSITION in kwargs:
            transition_time = int(kwargs[ATTR_TRANSITION]) * 10

        dimmer_command = None
        if ATTR_BRIGHTNESS in kwargs:
            brightness = kwargs[ATTR_BRIGHTNESS]
            brightness = min(brightness, 254)
            dimmer_data = {
                ATTR_DIMMER: brightness,
                ATTR_TRANSITION_TIME: transition_time,
            }
            dimmer_command = self._device_control.set_dimmer(**dimmer_data)
            transition_time = None
        else:
            dimmer_command = self._device_control.set_state(True)

        color_command = None
        if ATTR_HS_COLOR in kwargs and self._device_control.can_set_color:
            hue = int(kwargs[ATTR_HS_COLOR][0] *
                      (self._device_control.max_hue / 360))
            sat = int(kwargs[ATTR_HS_COLOR][1] *
                      (self._device_control.max_saturation / 100))
            color_data = {
                ATTR_HUE: hue,
                ATTR_SAT: sat,
                ATTR_TRANSITION_TIME: transition_time,
            }
            color_command = self._device_control.set_hsb(**color_data)
            transition_time = None

        temp_command = None
        if ATTR_COLOR_TEMP in kwargs and (self._device_control.can_set_temp or
                                          self._device_control.can_set_color):
            temp = kwargs[ATTR_COLOR_TEMP]
            # White Spectrum bulb
            if self._device_control.can_set_temp:
                if temp > self.max_mireds:
                    temp = self.max_mireds
                elif temp < self.min_mireds:
                    temp = self.min_mireds
                temp_data = {
                    ATTR_COLOR_TEMP: temp,
                    ATTR_TRANSITION_TIME: transition_time,
                }
                temp_command = self._device_control.set_color_temp(**temp_data)
                transition_time = None
            # Color bulb (CWS)
            # color_temp needs to be set with hue/saturation
            elif self._device_control.can_set_color:
                temp_k = color_util.color_temperature_mired_to_kelvin(temp)
                hs_color = color_util.color_temperature_to_hs(temp_k)
                hue = int(hs_color[0] * (self._device_control.max_hue / 360))
                sat = int(hs_color[1] *
                          (self._device_control.max_saturation / 100))
                color_data = {
                    ATTR_HUE: hue,
                    ATTR_SAT: sat,
                    ATTR_TRANSITION_TIME: transition_time,
                }
                color_command = self._device_control.set_hsb(**color_data)
                transition_time = None

        # HSB can always be set, but color temp + brightness is bulb dependent
        command = dimmer_command
        if command is not None:
            command += color_command
        else:
            command = color_command

        if self._device_control.can_combine_commands:
            await self._api(command + temp_command)
        else:
            if temp_command is not None:
                await self._api(temp_command)
            if command is not None:
                await self._api(command)
コード例 #14
0
async def test_services(opp: OpenPeerPower, caplog):
    """Test Yeelight services."""
    config_entry = MockConfigEntry(
        domain=DOMAIN,
        data={
            **CONFIG_ENTRY_DATA,
            CONF_MODE_MUSIC: True,
            CONF_SAVE_ON_CHANGE: True,
            CONF_NIGHTLIGHT_SWITCH: True,
        },
    )
    config_entry.add_to_opp(opp)

    mocked_bulb = _mocked_bulb()
    with _patch_discovery(MODULE), patch(f"{MODULE}.Bulb",
                                         return_value=mocked_bulb):
        assert await opp.config_entries.async_setup(config_entry.entry_id)
        await opp.async_block_till_done()

    async def _async_test_service(
        service,
        data,
        method,
        payload=None,
        domain=DOMAIN,
        failure_side_effect=BulbException,
    ):
        err_count = len(
            [x for x in caplog.records if x.levelno == logging.ERROR])

        # success
        mocked_method = MagicMock()
        setattr(type(mocked_bulb), method, mocked_method)
        await opp.services.async_call(domain, service, data, blocking=True)
        if payload is None:
            mocked_method.assert_called_once()
        elif type(payload) == list:
            mocked_method.assert_called_once_with(*payload)
        else:
            mocked_method.assert_called_once_with(**payload)
        assert (len([x for x in caplog.records
                     if x.levelno == logging.ERROR]) == err_count)

        # failure
        if failure_side_effect:
            mocked_method = MagicMock(side_effect=failure_side_effect)
            setattr(type(mocked_bulb), method, mocked_method)
            await opp.services.async_call(domain, service, data, blocking=True)
            assert (len([
                x for x in caplog.records if x.levelno == logging.ERROR
            ]) == err_count + 1)

    # turn_on
    brightness = 100
    color_temp = 200
    transition = 1
    await opp.services.async_call(
        "light",
        SERVICE_TURN_ON,
        {
            ATTR_ENTITY_ID: ENTITY_LIGHT,
            ATTR_BRIGHTNESS: brightness,
            ATTR_COLOR_TEMP: color_temp,
            ATTR_FLASH: FLASH_LONG,
            ATTR_EFFECT: EFFECT_STOP,
            ATTR_TRANSITION: transition,
        },
        blocking=True,
    )
    mocked_bulb.turn_on.assert_called_once_with(
        duration=transition * 1000,
        light_type=LightType.Main,
        power_mode=PowerMode.NORMAL,
    )
    mocked_bulb.turn_on.reset_mock()
    mocked_bulb.start_music.assert_called_once()
    mocked_bulb.set_brightness.assert_called_once_with(
        brightness / 255 * 100,
        duration=transition * 1000,
        light_type=LightType.Main)
    mocked_bulb.set_color_temp.assert_called_once_with(
        color_temperature_mired_to_kelvin(color_temp),
        duration=transition * 1000,
        light_type=LightType.Main,
    )
    mocked_bulb.start_flow.assert_called_once()  # flash
    mocked_bulb.stop_flow.assert_called_once_with(light_type=LightType.Main)

    # turn_on nightlight
    await _async_test_service(
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: ENTITY_NIGHTLIGHT},
        "turn_on",
        payload={
            "duration": DEFAULT_TRANSITION,
            "light_type": LightType.Main,
            "power_mode": PowerMode.MOONLIGHT,
        },
        domain="light",
    )

    # turn_off
    await _async_test_service(
        SERVICE_TURN_OFF,
        {
            ATTR_ENTITY_ID: ENTITY_LIGHT,
            ATTR_TRANSITION: transition
        },
        "turn_off",
        domain="light",
        payload={
            "duration": transition * 1000,
            "light_type": LightType.Main
        },
    )

    # set_mode
    mode = "rgb"
    await _async_test_service(
        SERVICE_SET_MODE,
        {
            ATTR_ENTITY_ID: ENTITY_LIGHT,
            ATTR_MODE: "rgb"
        },
        "set_power_mode",
        [PowerMode[mode.upper()]],
    )

    # start_flow
    await _async_test_service(
        SERVICE_START_FLOW,
        {
            ATTR_ENTITY_ID:
            ENTITY_LIGHT,
            ATTR_TRANSITIONS: [{
                YEELIGHT_TEMPERATURE_TRANSACTION: [1900, 2000, 60]
            }],
        },
        "start_flow",
    )

    # set_color_scene
    await _async_test_service(
        SERVICE_SET_COLOR_SCENE,
        {
            ATTR_ENTITY_ID: ENTITY_LIGHT,
            ATTR_RGB_COLOR: [10, 20, 30],
            ATTR_BRIGHTNESS: 50,
        },
        "set_scene",
        [SceneClass.COLOR, 10, 20, 30, 50],
    )

    # set_hsv_scene
    await _async_test_service(
        SERVICE_SET_HSV_SCENE,
        {
            ATTR_ENTITY_ID: ENTITY_LIGHT,
            ATTR_HS_COLOR: [180, 50],
            ATTR_BRIGHTNESS: 50
        },
        "set_scene",
        [SceneClass.HSV, 180, 50, 50],
    )

    # set_color_temp_scene
    await _async_test_service(
        SERVICE_SET_COLOR_TEMP_SCENE,
        {
            ATTR_ENTITY_ID: ENTITY_LIGHT,
            ATTR_KELVIN: 4000,
            ATTR_BRIGHTNESS: 50
        },
        "set_scene",
        [SceneClass.CT, 4000, 50],
    )

    # set_color_flow_scene
    await _async_test_service(
        SERVICE_SET_COLOR_FLOW_SCENE,
        {
            ATTR_ENTITY_ID:
            ENTITY_LIGHT,
            ATTR_TRANSITIONS: [{
                YEELIGHT_TEMPERATURE_TRANSACTION: [1900, 2000, 60]
            }],
        },
        "set_scene",
    )

    # set_auto_delay_off_scene
    await _async_test_service(
        SERVICE_SET_AUTO_DELAY_OFF_SCENE,
        {
            ATTR_ENTITY_ID: ENTITY_LIGHT,
            ATTR_MINUTES: 1,
            ATTR_BRIGHTNESS: 50
        },
        "set_scene",
        [SceneClass.AUTO_DELAY_OFF, 50, 1],
    )

    # set_music_mode failure enable
    await _async_test_service(
        SERVICE_SET_MUSIC_MODE,
        {
            ATTR_ENTITY_ID: ENTITY_LIGHT,
            ATTR_MODE_MUSIC: "true"
        },
        "start_music",
        failure_side_effect=AssertionError,
    )

    # set_music_mode disable
    await _async_test_service(
        SERVICE_SET_MUSIC_MODE,
        {
            ATTR_ENTITY_ID: ENTITY_LIGHT,
            ATTR_MODE_MUSIC: "false"
        },
        "stop_music",
        failure_side_effect=None,
    )

    # set_music_mode success enable
    await _async_test_service(
        SERVICE_SET_MUSIC_MODE,
        {
            ATTR_ENTITY_ID: ENTITY_LIGHT,
            ATTR_MODE_MUSIC: "true"
        },
        "start_music",
        failure_side_effect=None,
    )
    # test _cmd wrapper error handler
    err_count = len([x for x in caplog.records if x.levelno == logging.ERROR])
    type(mocked_bulb).turn_on = MagicMock()
    type(mocked_bulb).set_brightness = MagicMock(side_effect=BulbException)
    await opp.services.async_call(
        "light",
        SERVICE_TURN_ON,
        {
            ATTR_ENTITY_ID: ENTITY_LIGHT,
            ATTR_BRIGHTNESS: 50
        },
        blocking=True,
    )
    assert (len([x for x in caplog.records
                 if x.levelno == logging.ERROR]) == err_count + 1)