diff --git a/homeassistant/components/yeelight/__init__.py b/homeassistant/components/yeelight/__init__.py index a4ff947191e..e7f7b06f58f 100644 --- a/homeassistant/components/yeelight/__init__.py +++ b/homeassistant/components/yeelight/__init__.py @@ -36,6 +36,9 @@ from homeassistant.helpers.typing import ConfigType _LOGGER = logging.getLogger(__name__) +STATE_CHANGE_TIME = 0.25 # seconds + + DOMAIN = "yeelight" DATA_YEELIGHT = DOMAIN DATA_UPDATED = "yeelight_{}_data_updated" @@ -546,6 +549,17 @@ class YeelightScanner: self._async_stop_scan() +def update_needs_bg_power_workaround(data): + """Check if a push update needs the bg_power workaround. + + Some devices will push the incorrect state for bg_power. + + To work around this any time we are pushed an update + with bg_power, we force poll state which will be correct. + """ + return "bg_power" in data + + class YeelightDevice: """Represents single Yeelight device.""" @@ -692,12 +706,18 @@ class YeelightDevice: await self._async_update_properties() async_dispatcher_send(self._hass, DATA_UPDATED.format(self._host)) + async def _async_forced_update(self, _now): + """Call a forced update.""" + await self.async_update(True) + @callback def async_update_callback(self, data): """Update push from device.""" was_available = self._available self._available = data.get(KEY_CONNECTED, True) - if self._did_first_update and not was_available and self._available: + if update_needs_bg_power_workaround(data) or ( + self._did_first_update and not was_available and self._available + ): # On reconnect the properties may be out of sync # # We need to make sure the DEVICE_INITIALIZED dispatcher is setup @@ -708,7 +728,7 @@ class YeelightDevice: # to be called when async_setup_entry reaches the end of the # function # - asyncio.create_task(self.async_update(True)) + async_call_later(self._hass, STATE_CHANGE_TIME, self._async_forced_update) async_dispatcher_send(self._hass, DATA_UPDATED.format(self._host)) diff --git a/homeassistant/components/yeelight/light.py b/homeassistant/components/yeelight/light.py index 3f5bb29bab7..69dde0e75b6 100644 --- a/homeassistant/components/yeelight/light.py +++ b/homeassistant/components/yeelight/light.py @@ -1,7 +1,6 @@ """Light platform support for yeelight.""" from __future__ import annotations -import asyncio import logging import math @@ -210,9 +209,6 @@ SERVICE_SCHEMA_SET_AUTO_DELAY_OFF_SCENE = { } -STATE_CHANGE_TIME = 0.25 # seconds - - @callback def _transitions_config_parser(transitions): """Parse transitions config into initialized objects.""" @@ -252,13 +248,15 @@ def _async_cmd(func): # A network error happened, the bulb is likely offline now self.device.async_mark_unavailable() self.async_write_ha_state() + exc_message = str(ex) or type(ex) raise HomeAssistantError( - f"Error when calling {func.__name__} for bulb {self.device.name} at {self.device.host}: {ex}" + f"Error when calling {func.__name__} for bulb {self.device.name} at {self.device.host}: {exc_message}" ) from ex except BULB_EXCEPTIONS as ex: # The bulb likely responded but had an error + exc_message = str(ex) or type(ex) raise HomeAssistantError( - f"Error when calling {func.__name__} for bulb {self.device.name} at {self.device.host}: {ex}" + f"Error when calling {func.__name__} for bulb {self.device.name} at {self.device.host}: {exc_message}" ) from ex return _async_wrap @@ -762,11 +760,6 @@ class YeelightGenericLight(YeelightEntity, LightEntity): if self.config[CONF_SAVE_ON_CHANGE] and (brightness or colortemp or rgb): await self.async_set_default() - # Some devices (mainly nightlights) will not send back the on state so we need to force a refresh - await asyncio.sleep(STATE_CHANGE_TIME) - if not self.is_on: - await self.device.async_update(True) - @_async_cmd async def _async_turn_off(self, duration) -> None: """Turn off with a given transition duration wrapped with _async_cmd.""" @@ -782,10 +775,6 @@ class YeelightGenericLight(YeelightEntity, LightEntity): duration = int(kwargs.get(ATTR_TRANSITION) * 1000) # kwarg in s await self._async_turn_off(duration) - # Some devices will not send back the off state so we need to force a refresh - await asyncio.sleep(STATE_CHANGE_TIME) - if self.is_on: - await self.device.async_update(True) @_async_cmd async def async_set_mode(self, mode: str): @@ -850,10 +839,8 @@ class YeelightNightLightSupport: return PowerMode.NORMAL -class YeelightColorLightWithoutNightlightSwitch( - YeelightColorLightSupport, YeelightGenericLight -): - """Representation of a Color Yeelight light.""" +class YeelightWithoutNightlightSwitchMixIn: + """A mix-in for yeelights without a nightlight switch.""" @property def _brightness_property(self): @@ -861,9 +848,25 @@ class YeelightColorLightWithoutNightlightSwitch( # want to "current_brightness" since it will check # "bg_power" and main light could still be on if self.device.is_nightlight_enabled: - return "current_brightness" + return "nl_br" return super()._brightness_property + @property + def color_temp(self) -> int: + """Return the color temperature.""" + if self.device.is_nightlight_enabled: + # Enabling the nightlight locks the colortemp to max + return self._max_mireds + return super().color_temp + + +class YeelightColorLightWithoutNightlightSwitch( + YeelightColorLightSupport, + YeelightWithoutNightlightSwitchMixIn, + YeelightGenericLight, +): + """Representation of a Color Yeelight light.""" + class YeelightColorLightWithNightlightSwitch( YeelightNightLightSupport, YeelightColorLightSupport, YeelightGenericLight @@ -880,19 +883,12 @@ class YeelightColorLightWithNightlightSwitch( class YeelightWhiteTempWithoutNightlightSwitch( - YeelightWhiteTempLightSupport, YeelightGenericLight + YeelightWhiteTempLightSupport, + YeelightWithoutNightlightSwitchMixIn, + YeelightGenericLight, ): """White temp light, when nightlight switch is not set to light.""" - @property - def _brightness_property(self): - # If the nightlight is not active, we do not - # want to "current_brightness" since it will check - # "bg_power" and main light could still be on - if self.device.is_nightlight_enabled: - return "current_brightness" - return super()._brightness_property - class YeelightWithNightLight( YeelightNightLightSupport, YeelightWhiteTempLightSupport, YeelightGenericLight @@ -911,6 +907,9 @@ class YeelightWithNightLight( class YeelightNightLightMode(YeelightGenericLight): """Representation of a Yeelight when in nightlight mode.""" + _attr_color_mode = COLOR_MODE_BRIGHTNESS + _attr_supported_color_modes = {COLOR_MODE_BRIGHTNESS} + @property def unique_id(self) -> str: """Return a unique ID.""" @@ -941,8 +940,9 @@ class YeelightNightLightMode(YeelightGenericLight): return PowerMode.MOONLIGHT @property - def _predefined_effects(self): - return YEELIGHT_TEMP_ONLY_EFFECT_LIST + def supported_features(self): + """Flag no supported features.""" + return 0 class YeelightNightLightModeWithAmbientSupport(YeelightNightLightMode): @@ -962,11 +962,6 @@ class YeelightNightLightModeWithoutBrightnessControl(YeelightNightLightMode): _attr_color_mode = COLOR_MODE_ONOFF _attr_supported_color_modes = {COLOR_MODE_ONOFF} - @property - def supported_features(self): - """Flag no supported features.""" - return 0 - class YeelightWithAmbientWithoutNightlight(YeelightWhiteTempWithoutNightlightSwitch): """Representation of a Yeelight which has ambilight support. diff --git a/tests/components/yeelight/test_init.py b/tests/components/yeelight/test_init.py index cee798308c4..aed2025ab5d 100644 --- a/tests/components/yeelight/test_init.py +++ b/tests/components/yeelight/test_init.py @@ -13,6 +13,7 @@ from homeassistant.components.yeelight import ( DATA_DEVICE, DOMAIN, NIGHTLIGHT_SWITCH_TYPE_LIGHT, + STATE_CHANGE_TIME, ) from homeassistant.config_entries import ConfigEntryState from homeassistant.const import ( @@ -458,6 +459,8 @@ async def test_connection_dropped_resyncs_properties(hass: HomeAssistant): await hass.async_block_till_done() assert len(mocked_bulb.async_get_properties.mock_calls) == 1 mocked_bulb._async_callback({KEY_CONNECTED: True}) - await hass.async_block_till_done() + async_fire_time_changed( + hass, dt_util.utcnow() + timedelta(seconds=STATE_CHANGE_TIME) + ) await hass.async_block_till_done() assert len(mocked_bulb.async_get_properties.mock_calls) == 2 diff --git a/tests/components/yeelight/test_light.py b/tests/components/yeelight/test_light.py index f4cae17a30c..fd6e12f2635 100644 --- a/tests/components/yeelight/test_light.py +++ b/tests/components/yeelight/test_light.py @@ -545,25 +545,27 @@ async def test_update_errors(hass: HomeAssistant, caplog): # Timeout usually means the bulb is overloaded with commands # but will still respond eventually. - mocked_bulb.async_get_properties = AsyncMock(side_effect=asyncio.TimeoutError) - await hass.services.async_call( - "light", - SERVICE_TURN_OFF, - {ATTR_ENTITY_ID: ENTITY_LIGHT}, - blocking=True, - ) + mocked_bulb.async_turn_off = AsyncMock(side_effect=asyncio.TimeoutError) + with pytest.raises(HomeAssistantError): + await hass.services.async_call( + "light", + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: ENTITY_LIGHT}, + blocking=True, + ) assert hass.states.get(ENTITY_LIGHT).state == STATE_ON # socket.error usually means the bulb dropped the connection # or lost wifi, then came back online and forced the existing # connection closed with a TCP RST - mocked_bulb.async_get_properties = AsyncMock(side_effect=socket.error) - await hass.services.async_call( - "light", - SERVICE_TURN_OFF, - {ATTR_ENTITY_ID: ENTITY_LIGHT}, - blocking=True, - ) + mocked_bulb.async_turn_off = AsyncMock(side_effect=socket.error) + with pytest.raises(HomeAssistantError): + await hass.services.async_call( + "light", + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: ENTITY_LIGHT}, + blocking=True, + ) assert hass.states.get(ENTITY_LIGHT).state == STATE_UNAVAILABLE @@ -572,6 +574,7 @@ async def test_state_already_set_avoid_ratelimit(hass: HomeAssistant): mocked_bulb = _mocked_bulb() properties = {**PROPERTIES} properties.pop("active_mode") + properties.pop("nl_br") properties["color_mode"] = "3" # HSV mocked_bulb.last_properties = properties mocked_bulb.bulb_type = BulbType.Color @@ -579,7 +582,9 @@ async def test_state_already_set_avoid_ratelimit(hass: HomeAssistant): domain=DOMAIN, data={**CONFIG_ENTRY_DATA, CONF_NIGHTLIGHT_SWITCH: False} ) config_entry.add_to_hass(hass) - with patch(f"{MODULE}.AsyncBulb", return_value=mocked_bulb): + with _patch_discovery(), _patch_discovery_interval(), patch( + f"{MODULE}.AsyncBulb", return_value=mocked_bulb + ): assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() # We use asyncio.create_task now to avoid @@ -623,7 +628,7 @@ async def test_state_already_set_avoid_ratelimit(hass: HomeAssistant): SERVICE_TURN_ON, { ATTR_ENTITY_ID: ENTITY_LIGHT, - ATTR_BRIGHTNESS_PCT: PROPERTIES["current_brightness"], + ATTR_BRIGHTNESS_PCT: PROPERTIES["bright"], }, blocking=True, ) @@ -696,9 +701,10 @@ async def test_device_types(hass: HomeAssistant, caplog): bulb_type, model, target_properties, - nightlight_properties=None, + nightlight_entity_properties=None, name=UNIQUE_FRIENDLY_NAME, entity_id=ENTITY_LIGHT, + nightlight_mode_properties=None, ): config_entry = MockConfigEntry( domain=DOMAIN, data={**CONFIG_ENTRY_DATA, CONF_NIGHTLIGHT_SWITCH: False} @@ -708,6 +714,9 @@ async def test_device_types(hass: HomeAssistant, caplog): mocked_bulb.bulb_type = bulb_type model_specs = _MODEL_SPECS.get(model) type(mocked_bulb).get_model_specs = MagicMock(return_value=model_specs) + original_nightlight_brightness = mocked_bulb.last_properties["nl_br"] + + mocked_bulb.last_properties["nl_br"] = "0" await _async_setup(config_entry) state = hass.states.get(entity_id) @@ -715,41 +724,58 @@ async def test_device_types(hass: HomeAssistant, caplog): assert state.state == "on" target_properties["friendly_name"] = name target_properties["flowing"] = False - target_properties["night_light"] = True + target_properties["night_light"] = False target_properties["music_mode"] = False assert dict(state.attributes) == target_properties - await hass.config_entries.async_unload(config_entry.entry_id) await config_entry.async_remove(hass) registry = er.async_get(hass) registry.async_clear_config_entry(config_entry.entry_id) + mocked_bulb.last_properties["nl_br"] = original_nightlight_brightness - # nightlight - if nightlight_properties is None: - return - config_entry = MockConfigEntry( - domain=DOMAIN, data={**CONFIG_ENTRY_DATA, CONF_NIGHTLIGHT_SWITCH: True} - ) - config_entry.add_to_hass(hass) - await _async_setup(config_entry) + # nightlight as a setting of the main entity + if nightlight_mode_properties is not None: + mocked_bulb.last_properties["active_mode"] = True + config_entry.add_to_hass(hass) + await _async_setup(config_entry) + state = hass.states.get(entity_id) + assert state.state == "on" + nightlight_mode_properties["friendly_name"] = name + nightlight_mode_properties["flowing"] = False + nightlight_mode_properties["night_light"] = True + nightlight_mode_properties["music_mode"] = False + assert dict(state.attributes) == nightlight_mode_properties - assert hass.states.get(entity_id).state == "off" - state = hass.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 hass.config_entries.async_unload(config_entry.entry_id) + await config_entry.async_remove(hass) + registry.async_clear_config_entry(config_entry.entry_id) + await hass.async_block_till_done() + mocked_bulb.last_properties.pop("active_mode") - await hass.config_entries.async_unload(config_entry.entry_id) - await config_entry.async_remove(hass) - registry.async_clear_config_entry(config_entry.entry_id) - await hass.async_block_till_done() + # nightlight as a separate entity + if nightlight_entity_properties is not None: + config_entry = MockConfigEntry( + domain=DOMAIN, data={**CONFIG_ENTRY_DATA, CONF_NIGHTLIGHT_SWITCH: True} + ) + config_entry.add_to_hass(hass) + await _async_setup(config_entry) + + assert hass.states.get(entity_id).state == "off" + state = hass.states.get(f"{entity_id}_nightlight") + assert state.state == "on" + nightlight_entity_properties["friendly_name"] = f"{name} Nightlight" + nightlight_entity_properties["icon"] = "mdi:weather-night" + nightlight_entity_properties["flowing"] = False + nightlight_entity_properties["night_light"] = True + nightlight_entity_properties["music_mode"] = False + assert dict(state.attributes) == nightlight_entity_properties + + await hass.config_entries.async_unload(config_entry.entry_id) + await config_entry.async_remove(hass) + registry.async_clear_config_entry(config_entry.entry_id) + await hass.async_block_till_done() 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"]) @@ -806,7 +832,7 @@ async def test_device_types(hass: HomeAssistant, caplog): "max_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["min"] ), - "brightness": current_brightness, + "brightness": bright, "color_temp": ct, "color_mode": "color_temp", "supported_color_modes": ["color_temp", "hs", "rgb"], @@ -814,11 +840,30 @@ async def test_device_types(hass: HomeAssistant, caplog): "rgb_color": (255, 205, 166), "xy_color": (0.421, 0.364), }, - { + nightlight_entity_properties={ "supported_features": 0, "color_mode": "onoff", "supported_color_modes": ["onoff"], }, + nightlight_mode_properties={ + "effect_list": YEELIGHT_COLOR_EFFECT_LIST, + "supported_features": SUPPORT_YEELIGHT, + "hs_color": (28.401, 100.0), + "rgb_color": (255, 120, 0), + "xy_color": (0.621, 0.367), + "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": nl_br, + "color_mode": "color_temp", + "supported_color_modes": ["color_temp", "hs", "rgb"], + "color_temp": color_temperature_kelvin_to_mired( + model_specs["color_temp"]["min"] + ), + }, ) # Color - color mode HS @@ -836,14 +881,14 @@ async def test_device_types(hass: HomeAssistant, caplog): "max_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["min"] ), - "brightness": current_brightness, + "brightness": bright, "hs_color": hs_color, "rgb_color": color_hs_to_RGB(*hs_color), "xy_color": color_hs_to_xy(*hs_color), "color_mode": "hs", "supported_color_modes": ["color_temp", "hs", "rgb"], }, - { + nightlight_entity_properties={ "supported_features": 0, "color_mode": "onoff", "supported_color_modes": ["onoff"], @@ -865,14 +910,14 @@ async def test_device_types(hass: HomeAssistant, caplog): "max_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["min"] ), - "brightness": current_brightness, + "brightness": bright, "hs_color": color_RGB_to_hs(*rgb_color), "rgb_color": rgb_color, "xy_color": color_RGB_to_xy(*rgb_color), "color_mode": "rgb", "supported_color_modes": ["color_temp", "hs", "rgb"], }, - { + nightlight_entity_properties={ "supported_features": 0, "color_mode": "onoff", "supported_color_modes": ["onoff"], @@ -895,11 +940,11 @@ async def test_device_types(hass: HomeAssistant, caplog): "max_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["min"] ), - "brightness": current_brightness, + "brightness": bright, "color_mode": "hs", "supported_color_modes": ["color_temp", "hs", "rgb"], }, - { + nightlight_entity_properties={ "supported_features": 0, "color_mode": "onoff", "supported_color_modes": ["onoff"], @@ -922,11 +967,11 @@ async def test_device_types(hass: HomeAssistant, caplog): "max_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["min"] ), - "brightness": current_brightness, + "brightness": bright, "color_mode": "rgb", "supported_color_modes": ["color_temp", "hs", "rgb"], }, - { + nightlight_entity_properties={ "supported_features": 0, "color_mode": "onoff", "supported_color_modes": ["onoff"], @@ -973,7 +1018,7 @@ async def test_device_types(hass: HomeAssistant, caplog): "max_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["min"] ), - "brightness": current_brightness, + "brightness": bright, "color_temp": ct, "color_mode": "color_temp", "supported_color_modes": ["color_temp"], @@ -981,13 +1026,31 @@ async def test_device_types(hass: HomeAssistant, caplog): "rgb_color": (255, 205, 166), "xy_color": (0.421, 0.364), }, - { - "effect_list": YEELIGHT_TEMP_ONLY_EFFECT_LIST, - "supported_features": SUPPORT_YEELIGHT, + nightlight_entity_properties={ + "supported_features": 0, "brightness": nl_br, "color_mode": "brightness", "supported_color_modes": ["brightness"], }, + nightlight_mode_properties={ + "effect_list": YEELIGHT_TEMP_ONLY_EFFECT_LIST, + "supported_features": SUPPORT_YEELIGHT, + "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": nl_br, + "color_temp": color_temperature_kelvin_to_mired( + model_specs["color_temp"]["min"] + ), + "color_mode": "color_temp", + "supported_color_modes": ["color_temp"], + "hs_color": (28.391, 65.659), + "rgb_color": (255, 166, 87), + "xy_color": (0.526, 0.387), + }, ) # WhiteTempMood @@ -1009,7 +1072,7 @@ async def test_device_types(hass: HomeAssistant, caplog): "max_mireds": color_temperature_kelvin_to_mired( model_specs["color_temp"]["min"] ), - "brightness": current_brightness, + "brightness": bright, "color_temp": ct, "color_mode": "color_temp", "supported_color_modes": ["color_temp"], @@ -1017,13 +1080,34 @@ async def test_device_types(hass: HomeAssistant, caplog): "rgb_color": (255, 205, 166), "xy_color": (0.421, 0.364), }, - { - "effect_list": YEELIGHT_TEMP_ONLY_EFFECT_LIST, - "supported_features": SUPPORT_YEELIGHT, + nightlight_entity_properties={ + "supported_features": 0, "brightness": nl_br, "color_mode": "brightness", "supported_color_modes": ["brightness"], }, + nightlight_mode_properties={ + "friendly_name": NAME, + "effect_list": YEELIGHT_TEMP_ONLY_EFFECT_LIST, + "flowing": False, + "night_light": True, + "supported_features": SUPPORT_YEELIGHT, + "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": nl_br, + "color_temp": color_temperature_kelvin_to_mired( + model_specs["color_temp"]["min"] + ), + "color_mode": "color_temp", + "supported_color_modes": ["color_temp"], + "hs_color": (28.391, 65.659), + "rgb_color": (255, 166, 87), + "xy_color": (0.526, 0.387), + }, ) # Background light - color mode CT mocked_bulb.last_properties["bg_lmode"] = "2" # CT @@ -1261,62 +1345,6 @@ async def test_effects(hass: HomeAssistant): await _async_test_effect("not_existed", called=False) -async def test_state_fails_to_update_triggers_update(hass: HomeAssistant): - """Ensure we call async_get_properties if the turn on/off fails to update the state.""" - mocked_bulb = _mocked_bulb() - properties = {**PROPERTIES} - properties.pop("active_mode") - properties["color_mode"] = "3" # HSV - mocked_bulb.last_properties = properties - mocked_bulb.bulb_type = BulbType.Color - config_entry = MockConfigEntry( - domain=DOMAIN, data={**CONFIG_ENTRY_DATA, CONF_NIGHTLIGHT_SWITCH: False} - ) - config_entry.add_to_hass(hass) - with patch(f"{MODULE}.AsyncBulb", return_value=mocked_bulb): - assert await hass.config_entries.async_setup(config_entry.entry_id) - await hass.async_block_till_done() - # We use asyncio.create_task now to avoid - # blocking starting so we need to block again - await hass.async_block_till_done() - - mocked_bulb.last_properties["power"] = "off" - await hass.services.async_call( - "light", - SERVICE_TURN_ON, - { - ATTR_ENTITY_ID: ENTITY_LIGHT, - }, - blocking=True, - ) - assert len(mocked_bulb.async_turn_on.mock_calls) == 1 - assert len(mocked_bulb.async_get_properties.mock_calls) == 2 - - mocked_bulb.last_properties["power"] = "on" - await hass.services.async_call( - "light", - SERVICE_TURN_OFF, - { - ATTR_ENTITY_ID: ENTITY_LIGHT, - }, - blocking=True, - ) - assert len(mocked_bulb.async_turn_off.mock_calls) == 1 - assert len(mocked_bulb.async_get_properties.mock_calls) == 3 - - # But if the state is correct no calls - await hass.services.async_call( - "light", - SERVICE_TURN_ON, - { - ATTR_ENTITY_ID: ENTITY_LIGHT, - }, - blocking=True, - ) - assert len(mocked_bulb.async_turn_on.mock_calls) == 1 - assert len(mocked_bulb.async_get_properties.mock_calls) == 3 - - async def test_ambilight_with_nightlight_disabled(hass: HomeAssistant): """Test that main light on ambilights with the nightlight disabled shows the correct brightness.""" mocked_bulb = _mocked_bulb() @@ -1325,7 +1353,6 @@ async def test_ambilight_with_nightlight_disabled(hass: HomeAssistant): capabilities["model"] = "ceiling10" properties["color_mode"] = "3" # HSV properties["bg_power"] = "off" - properties["current_brightness"] = 0 properties["bg_lmode"] = "2" # CT mocked_bulb.last_properties = properties mocked_bulb.bulb_type = BulbType.WhiteTempMood