diff --git a/homeassistant/components/lifx/light.py b/homeassistant/components/lifx/light.py index 444bfe31480..e775b5623d3 100644 --- a/homeassistant/components/lifx/light.py +++ b/homeassistant/components/lifx/light.py @@ -199,11 +199,11 @@ def lifx_features(bulb): ) or aiolifx().products.features_map.get(1) -def find_hsbk(**kwargs): +def find_hsbk(hass, **kwargs): """Find the desired color from a number of possible inputs.""" hue, saturation, brightness, kelvin = [None] * 4 - preprocess_turn_on_alternatives(kwargs) + preprocess_turn_on_alternatives(hass, kwargs) if ATTR_HS_COLOR in kwargs: hue, saturation = kwargs[ATTR_HS_COLOR] @@ -330,11 +330,11 @@ class LIFXManager: period=kwargs.get(ATTR_PERIOD), cycles=kwargs.get(ATTR_CYCLES), mode=kwargs.get(ATTR_MODE), - hsbk=find_hsbk(**kwargs), + hsbk=find_hsbk(self.hass, **kwargs), ) await self.effects_conductor.start(effect, bulbs) elif service == SERVICE_EFFECT_COLORLOOP: - preprocess_turn_on_alternatives(kwargs) + preprocess_turn_on_alternatives(self.hass, kwargs) brightness = None if ATTR_BRIGHTNESS in kwargs: @@ -600,7 +600,7 @@ class LIFXLight(LightEntity): power_on = kwargs.get(ATTR_POWER, False) power_off = not kwargs.get(ATTR_POWER, True) - hsbk = find_hsbk(**kwargs) + hsbk = find_hsbk(self.hass, **kwargs) # Send messages, waiting for ACK each time ack = AwaitAioLIFX().wait diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index a179eca6957..fdef5e61a76 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -3,7 +3,6 @@ import csv from datetime import timedelta import logging import os -from typing import Dict, Optional, Tuple import voluptuous as vol @@ -13,6 +12,7 @@ from homeassistant.const import ( SERVICE_TURN_ON, STATE_ON, ) +from homeassistant.core import callback import homeassistant.helpers.config_validation as cv from homeassistant.helpers.config_validation import ( # noqa: F401 PLATFORM_SCHEMA, @@ -28,6 +28,7 @@ import homeassistant.util.color as color_util DOMAIN = "light" SCAN_INTERVAL = timedelta(seconds=30) +DATA_PROFILES = "light_profiles" ENTITY_ID_FORMAT = DOMAIN + ".{}" @@ -122,15 +123,6 @@ LIGHT_TURN_ON_SCHEMA = { } -PROFILE_SCHEMA = vol.Schema( - vol.Any( - vol.ExactSequence((str, cv.small_float, cv.small_float, cv.byte)), - vol.ExactSequence( - (str, cv.small_float, cv.small_float, cv.byte, cv.positive_int) - ), - ) -) - _LOGGER = logging.getLogger(__name__) @@ -140,14 +132,17 @@ def is_on(hass, entity_id): return hass.states.is_state(entity_id, STATE_ON) -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]) - if len(profile) > 3: - params.setdefault(ATTR_TRANSITION, profile[3]) +def preprocess_turn_on_alternatives(hass, params): + """Process extra data for turn light on request. + + Async friendly. + """ + # Bail out, we process this later. + if ATTR_BRIGHTNESS_STEP in params or ATTR_BRIGHTNESS_STEP_PCT in params: + return + + if ATTR_PROFILE in params: + hass.data[DATA_PROFILES].apply_profile(params.pop(ATTR_PROFILE), params) color_name = params.pop(ATTR_COLOR_NAME, None) if color_name is not None: @@ -174,24 +169,12 @@ def preprocess_turn_on_alternatives(params): if rgb_color is not None: params[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color) - return params - def filter_turn_off_params(params): """Filter out params not used in turn off.""" return {k: v for k, v in params.items() if k in (ATTR_TRANSITION, ATTR_FLASH)} -def preprocess_turn_off(params): - """Process data for turning light off if brightness is 0.""" - if ATTR_BRIGHTNESS in params and params[ATTR_BRIGHTNESS] == 0: - # Zero brightness: Light will be turned off - params = filter_turn_off_params(params) - return (True, params) # Light should be turned off - - return (False, None) # Light should be turned on - - async def async_setup(hass, config): """Expose light control via state machine and services.""" component = hass.data[DOMAIN] = EntityComponent( @@ -199,10 +182,8 @@ async def async_setup(hass, config): ) await component.async_setup(config) - # load profiles from files - profiles_valid = await Profiles.load_profiles(hass) - if not profiles_valid: - return False + profiles = hass.data[DATA_PROFILES] = Profiles(hass) + await profiles.async_initialize() def preprocess_data(data): """Preprocess the service data.""" @@ -212,7 +193,8 @@ async def async_setup(hass, config): if entity_field in data } - base["params"] = preprocess_turn_on_alternatives(data) + preprocess_turn_on_alternatives(hass, data) + base["params"] = data return base async def async_handle_light_on_service(light, call): @@ -223,17 +205,14 @@ async def async_setup(hass, config): params = call.data["params"] if not params: - default_profile = Profiles.get_default(light.entity_id) + profiles.apply_default(light.entity_id, params) - if default_profile is not None: - params = {ATTR_PROFILE: default_profile} - preprocess_turn_on_alternatives(params) - - elif ATTR_BRIGHTNESS_STEP in params or ATTR_BRIGHTNESS_STEP_PCT in 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 - params = params.copy() - if ATTR_BRIGHTNESS_STEP in params: brightness += params.pop(ATTR_BRIGHTNESS_STEP) @@ -242,19 +221,18 @@ async def async_setup(hass, config): params[ATTR_BRIGHTNESS] = max(0, min(255, brightness)) - turn_light_off, off_params = preprocess_turn_off(params) - if turn_light_off: - await light.async_turn_off(**off_params) + preprocess_turn_on_alternatives(hass, params) + + # Zero brightness: Light will be turned off + if params.get(ATTR_BRIGHTNESS) == 0: + await light.async_turn_off(**filter_turn_off_params(params)) else: await light.async_turn_on(**params) async def async_handle_toggle_service(light, call): - """Handle toggling a light. - - If brightness is set to 0, this service will turn the light off. - """ + """Handle toggling a light.""" if light.is_on: - off_params = filter_turn_off_params(call.data["params"]) + off_params = filter_turn_off_params(call.data) await light.async_turn_off(**off_params) else: await async_handle_light_on_service(light, call) @@ -295,73 +273,89 @@ async def async_unload_entry(hass, entry): class Profiles: """Representation of available color profiles.""" - _all: Optional[Dict[str, Tuple[float, float, int]]] = None + SCHEMA = vol.Schema( + vol.Any( + vol.ExactSequence((str, cv.small_float, cv.small_float, cv.byte)), + vol.ExactSequence( + (str, cv.small_float, cv.small_float, cv.byte, cv.positive_int) + ), + ) + ) - @classmethod - async def load_profiles(cls, hass): - """Load and cache profiles.""" + def __init__(self, hass): + """Initialize profiles.""" + self.hass = hass + self.data = None - def load_profile_data(hass): - """Load built-in profiles and custom profiles.""" - profile_paths = [ - os.path.join(os.path.dirname(__file__), LIGHT_PROFILES_FILE), - hass.config.path(LIGHT_PROFILES_FILE), - ] - profiles = {} + def _load_profile_data(self): + """Load built-in profiles and custom profiles.""" + profile_paths = [ + os.path.join(os.path.dirname(__file__), LIGHT_PROFILES_FILE), + self.hass.config.path(LIGHT_PROFILES_FILE), + ] + profiles = {} - for profile_path in profile_paths: - if not os.path.isfile(profile_path): - continue - with open(profile_path) as inp: - reader = csv.reader(inp) + for profile_path in profile_paths: + if not os.path.isfile(profile_path): + continue + with open(profile_path) as inp: + reader = csv.reader(inp) - # Skip the header - next(reader, None) + # Skip the header + next(reader, None) - try: - for rec in reader: - ( - profile, - color_x, - color_y, - brightness, - *transition, - ) = PROFILE_SCHEMA(rec) + try: + for rec in reader: + ( + profile, + color_x, + color_y, + brightness, + *transition, + ) = Profiles.SCHEMA(rec) - transition = transition[0] if transition else 0 + transition = transition[0] if transition else 0 - profiles[profile] = ( - color_x, - color_y, - brightness, - transition, - ) - except vol.MultipleInvalid as ex: - _LOGGER.error( - "Error parsing light profile from %s: %s", profile_path, ex + profiles[profile] = color_util.color_xy_to_hs( + color_x, color_y + ) + ( + brightness, + transition, ) - return None - return profiles + except vol.MultipleInvalid as ex: + _LOGGER.error( + "Error parsing light profile from %s: %s", profile_path, ex + ) + continue + return profiles - cls._all = await hass.async_add_executor_job(load_profile_data, hass) - return cls._all is not None + async def async_initialize(self): + """Load and cache profiles.""" + self.data = await self.hass.async_add_executor_job(self._load_profile_data) - @classmethod - def get(cls, name): - """Return a named profile.""" - return cls._all.get(name) - - @classmethod - def get_default(cls, entity_id): + @callback + def apply_default(self, entity_id, params): """Return the default turn-on profile for the given light.""" - # pylint: disable=unsupported-membership-test name = f"{entity_id}.default" - if name in cls._all: - return name + if name in self.data: + self.apply_profile(name, params) + return + name = "group.all_lights.default" - if name in cls._all: - return name - return None + if name in self.data: + self.apply_profile(name, params) + + @callback + def apply_profile(self, name, params): + """Apply a profile.""" + profile = self.data.get(name) + + if profile is None: + return + + params.setdefault(ATTR_HS_COLOR, profile[:2]) + params.setdefault(ATTR_BRIGHTNESS, profile[2]) + params.setdefault(ATTR_TRANSITION, profile[3]) class LightEntity(ToggleEntity): diff --git a/tests/components/abode/conftest.py b/tests/components/abode/conftest.py index 681f65ddf93..cc18597c56e 100644 --- a/tests/components/abode/conftest.py +++ b/tests/components/abode/conftest.py @@ -3,6 +3,7 @@ import abodepy.helpers.constants as CONST import pytest from tests.common import load_fixture +from tests.components.light.conftest import mock_light_profiles # noqa @pytest.fixture(autouse=True) diff --git a/tests/components/axis/conftest.py b/tests/components/axis/conftest.py new file mode 100644 index 00000000000..33ea820f9cf --- /dev/null +++ b/tests/components/axis/conftest.py @@ -0,0 +1,2 @@ +"""axis conftest.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/blebox/conftest.py b/tests/components/blebox/conftest.py index ece02d50b39..e43fb9fc4b4 100644 --- a/tests/components/blebox/conftest.py +++ b/tests/components/blebox/conftest.py @@ -1,5 +1,4 @@ """PyTest fixtures and test helpers.""" - from unittest import mock import blebox_uniapi @@ -11,6 +10,7 @@ from homeassistant.setup import async_setup_component from tests.async_mock import AsyncMock, PropertyMock, patch from tests.common import MockConfigEntry +from tests.components.light.conftest import mock_light_profiles # noqa def patch_product_identify(path=None, **kwargs): diff --git a/tests/components/bond/conftest.py b/tests/components/bond/conftest.py new file mode 100644 index 00000000000..7ab1805cb73 --- /dev/null +++ b/tests/components/bond/conftest.py @@ -0,0 +1,2 @@ +"""bond conftest.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/deconz/conftest.py b/tests/components/deconz/conftest.py new file mode 100644 index 00000000000..4c45d3c912b --- /dev/null +++ b/tests/components/deconz/conftest.py @@ -0,0 +1,2 @@ +"""deconz conftest.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/demo/conftest.py b/tests/components/demo/conftest.py new file mode 100644 index 00000000000..666224fb737 --- /dev/null +++ b/tests/components/demo/conftest.py @@ -0,0 +1,2 @@ +"""demo conftest.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/dynalite/conftest.py b/tests/components/dynalite/conftest.py new file mode 100644 index 00000000000..187e4f9cbaa --- /dev/null +++ b/tests/components/dynalite/conftest.py @@ -0,0 +1,2 @@ +"""dynalite conftest.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/elgato/conftest.py b/tests/components/elgato/conftest.py new file mode 100644 index 00000000000..f2ac45155fb --- /dev/null +++ b/tests/components/elgato/conftest.py @@ -0,0 +1,2 @@ +"""elgato conftest.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/everlights/conftest.py b/tests/components/everlights/conftest.py new file mode 100644 index 00000000000..31915934b31 --- /dev/null +++ b/tests/components/everlights/conftest.py @@ -0,0 +1,2 @@ +"""everlights conftest.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/group/conftest.py b/tests/components/group/conftest.py new file mode 100644 index 00000000000..6fe34aca91c --- /dev/null +++ b/tests/components/group/conftest.py @@ -0,0 +1,2 @@ +"""group conftest.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/homekit_controller/conftest.py b/tests/components/homekit_controller/conftest.py index 3b023e0da51..dbb1db36aa7 100644 --- a/tests/components/homekit_controller/conftest.py +++ b/tests/components/homekit_controller/conftest.py @@ -8,6 +8,7 @@ import pytest import homeassistant.util.dt as dt_util import tests.async_mock +from tests.components.light.conftest import mock_light_profiles # noqa @pytest.fixture diff --git a/tests/components/homematicip_cloud/conftest.py b/tests/components/homematicip_cloud/conftest.py index 3ada7e7de0a..b967ef79094 100644 --- a/tests/components/homematicip_cloud/conftest.py +++ b/tests/components/homematicip_cloud/conftest.py @@ -24,6 +24,7 @@ from .helper import AUTH_TOKEN, HAPID, HAPPIN, HomeFactory from tests.async_mock import AsyncMock, MagicMock, Mock, patch from tests.common import MockConfigEntry +from tests.components.light.conftest import mock_light_profiles # noqa @pytest.fixture(name="mock_connection") diff --git a/tests/components/hue/conftest.py b/tests/components/hue/conftest.py index 094378f47c9..55b6443bdfa 100644 --- a/tests/components/hue/conftest.py +++ b/tests/components/hue/conftest.py @@ -12,6 +12,7 @@ from homeassistant.components import hue from homeassistant.components.hue import sensor_base as hue_sensor_base from tests.async_mock import AsyncMock, Mock, patch +from tests.components.light.conftest import mock_light_profiles # noqa @pytest.fixture(autouse=True) diff --git a/tests/components/hyperion/conftest.py b/tests/components/hyperion/conftest.py new file mode 100644 index 00000000000..4eb59770fae --- /dev/null +++ b/tests/components/hyperion/conftest.py @@ -0,0 +1,2 @@ +"""hyperion conftest.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/light/conftest.py b/tests/components/light/conftest.py new file mode 100644 index 00000000000..67af99a3d6c --- /dev/null +++ b/tests/components/light/conftest.py @@ -0,0 +1,26 @@ +"""Light conftest.""" + +import pytest + +from homeassistant.components.light import Profiles + +from tests.async_mock import AsyncMock, patch + + +@pytest.fixture(autouse=True) +def mock_light_profiles(): + """Mock loading of profiles.""" + data = {} + + def mock_profiles_class(hass): + profiles = Profiles(hass) + profiles.data = data + profiles.async_initialize = AsyncMock() + return profiles + + with patch( + "homeassistant.components.light.Profiles", + SCHEMA=Profiles.SCHEMA, + side_effect=mock_profiles_class, + ): + yield data diff --git a/tests/components/light/test_init.py b/tests/components/light/test_init.py index e723ac77e03..afc125e6423 100644 --- a/tests/components/light/test_init.py +++ b/tests/components/light/test_init.py @@ -1,8 +1,4 @@ """The tests for the Light component.""" -# pylint: disable=protected-access -from io import StringIO -import os - import pytest import voluptuous as vol @@ -20,19 +16,11 @@ from homeassistant.const import ( ) from homeassistant.exceptions import Unauthorized from homeassistant.setup import async_setup_component +from homeassistant.util import color -import tests.async_mock as mock from tests.common import async_mock_service - -@pytest.fixture -def mock_storage(hass, hass_storage): - """Clean up user light files at the end.""" - yield - user_light_file = hass.config.path(light.LIGHT_PROFILES_FILE) - - if os.path.isfile(user_light_file): - os.remove(user_light_file) +orig_Profiles = light.Profiles async def test_methods(hass): @@ -117,7 +105,7 @@ async def test_methods(hass): assert call.data[light.ATTR_TRANSITION] == "transition_val" -async def test_services(hass): +async def test_services(hass, mock_light_profiles): """Test the provided services.""" platform = getattr(hass.components, "test.light") @@ -292,6 +280,7 @@ async def test_services(hass): assert data == {} # One of the light profiles + mock_light_profiles["relax"] = (35.932, 69.412, 144, 0) prof_name, prof_h, prof_s, prof_bri, prof_t = "relax", 35.932, 69.412, 144, 0 # Test light profiles @@ -418,34 +407,13 @@ async def test_services(hass): assert data == {} -async def test_broken_light_profiles(hass, mock_storage): +async def test_light_profiles(hass, mock_light_profiles): """Test light profiles.""" platform = getattr(hass.components, "test.light") platform.init() - user_light_file = hass.config.path(light.LIGHT_PROFILES_FILE) - - # Setup a wrong light file - with open(user_light_file, "w") as user_file: - user_file.write("id,x,y,brightness,transition\n") - user_file.write("I,WILL,NOT,WORK,EVER\n") - - assert not await async_setup_component( - hass, light.DOMAIN, {light.DOMAIN: {CONF_PLATFORM: "test"}} - ) - - -async def test_light_profiles(hass, mock_storage): - """Test light profiles.""" - platform = getattr(hass.components, "test.light") - platform.init() - - user_light_file = hass.config.path(light.LIGHT_PROFILES_FILE) - - with open(user_light_file, "w") as user_file: - user_file.write("id,x,y,brightness\n") - user_file.write("test,.4,.6,100\n") - user_file.write("test_off,0,0,0\n") + 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"}} @@ -484,80 +452,21 @@ async def test_light_profiles(hass, mock_storage): assert data == {light.ATTR_TRANSITION: 0} -async def test_light_profiles_with_transition(hass, mock_storage): - """Test light profiles with transition.""" +async def test_default_profiles_group(hass, mock_light_profiles): + """Test default turn-on light profile for all lights.""" platform = getattr(hass.components, "test.light") platform.init() - user_light_file = hass.config.path(light.LIGHT_PROFILES_FILE) - - with open(user_light_file, "w") as user_file: - user_file.write("id,x,y,brightness,transition\n") - user_file.write("test,.4,.6,100,2\n") - user_file.write("test_off,0,0,0,0\n") - 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, + mock_light_profiles["group.all_lights.default"] = color.color_xy_to_hs(0.4, 0.6) + ( + 99, + 2, ) - _, 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: 2, - } - - 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} - - -async def test_default_profiles_group(hass, mock_storage): - """Test default turn-on light profile for all lights.""" - platform = getattr(hass.components, "test.light") - platform.init() - - user_light_file = hass.config.path(light.LIGHT_PROFILES_FILE) - real_isfile = os.path.isfile - real_open = open - - def _mock_isfile(path): - if path == user_light_file: - return True - return real_isfile(path) - - def _mock_open(path, *args, **kwargs): - if path == user_light_file: - return StringIO(profile_data) - return real_open(path, *args, **kwargs) - - profile_data = "id,x,y,brightness,transition\ngroup.all_lights.default,.4,.6,99,2\n" - with mock.patch("os.path.isfile", side_effect=_mock_isfile), mock.patch( - "builtins.open", side_effect=_mock_open - ): - assert await async_setup_component( - hass, light.DOMAIN, {light.DOMAIN: {CONF_PLATFORM: "test"}} - ) - await hass.async_block_till_done() - ent, _, _ = platform.ENTITIES await hass.services.async_call( light.DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ent.entity_id}, blocking=True @@ -571,37 +480,24 @@ async def test_default_profiles_group(hass, mock_storage): } -async def test_default_profiles_light(hass, mock_storage): +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() - user_light_file = hass.config.path(light.LIGHT_PROFILES_FILE) - real_isfile = os.path.isfile - real_open = open - - def _mock_isfile(path): - if path == user_light_file: - return True - return real_isfile(path) - - def _mock_open(path, *args, **kwargs): - if path == user_light_file: - return StringIO(profile_data) - return real_open(path, *args, **kwargs) - - profile_data = ( - "id,x,y,brightness,transition\n" - + "group.all_lights.default,.3,.5,200,0\n" - + "light.ceiling_2.default,.6,.6,100,3\n" + 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, ) - with mock.patch("os.path.isfile", side_effect=_mock_isfile), mock.patch( - "builtins.open", side_effect=_mock_open - ): - assert await async_setup_component( - hass, light.DOMAIN, {light.DOMAIN: {CONF_PLATFORM: "test"}} - ) - await hass.async_block_till_done() dev = next(filter(lambda x: x.entity_id == "light.ceiling_2", platform.ENTITIES)) await hass.services.async_call( @@ -775,3 +671,15 @@ def test_deprecated_base_class(caplog): CustomLight() assert "Light is deprecated, modify CustomLight" in caplog.text + + +async def test_profiles(hass): + """Test profiles loading.""" + profiles = orig_Profiles(hass) + await profiles.async_initialize() + assert profiles.data == { + "concentrate": (35.932, 69.412, 219, 0), + "energize": (43.333, 21.176, 203, 0), + "reading": (38.88, 49.02, 240, 0), + "relax": (35.932, 69.412, 144, 0), + } diff --git a/tests/components/litejet/conftest.py b/tests/components/litejet/conftest.py new file mode 100644 index 00000000000..68797f96ccf --- /dev/null +++ b/tests/components/litejet/conftest.py @@ -0,0 +1,2 @@ +"""litejet conftest.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/mochad/conftest.py b/tests/components/mochad/conftest.py new file mode 100644 index 00000000000..9b095046d9c --- /dev/null +++ b/tests/components/mochad/conftest.py @@ -0,0 +1,2 @@ +"""mochad conftest.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/mqtt/conftest.py b/tests/components/mqtt/conftest.py index 895327d1756..5f0acc3e5c2 100644 --- a/tests/components/mqtt/conftest.py +++ b/tests/components/mqtt/conftest.py @@ -1 +1,2 @@ """Test fixtures for mqtt component.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/ozw/conftest.py b/tests/components/ozw/conftest.py index 3af9594d868..e09dacd8342 100644 --- a/tests/components/ozw/conftest.py +++ b/tests/components/ozw/conftest.py @@ -7,6 +7,7 @@ from .common import MQTTMessage from tests.async_mock import patch from tests.common import load_fixture +from tests.components.light.conftest import mock_light_profiles # noqa @pytest.fixture(name="generic_data", scope="session") diff --git a/tests/components/rflink/conftest.py b/tests/components/rflink/conftest.py new file mode 100644 index 00000000000..f33c8ab89db --- /dev/null +++ b/tests/components/rflink/conftest.py @@ -0,0 +1,2 @@ +"""rflink conftest.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/rfxtrx/conftest.py b/tests/components/rfxtrx/conftest.py index 82c4bd7aacd..563fb362e5a 100644 --- a/tests/components/rfxtrx/conftest.py +++ b/tests/components/rfxtrx/conftest.py @@ -9,6 +9,7 @@ from homeassistant.util.dt import utcnow from tests.async_mock import patch from tests.common import MockConfigEntry, async_fire_time_changed +from tests.components.light.conftest import mock_light_profiles # noqa def create_rfx_test_cfg(device="abcd", automatic_add=False, devices=None): diff --git a/tests/components/ring/conftest.py b/tests/components/ring/conftest.py index 5df85662ac8..f2e05189dea 100644 --- a/tests/components/ring/conftest.py +++ b/tests/components/ring/conftest.py @@ -5,6 +5,7 @@ import pytest import requests_mock from tests.common import load_fixture +from tests.components.light.conftest import mock_light_profiles # noqa @pytest.fixture(name="requests_mock") diff --git a/tests/components/smartthings/conftest.py b/tests/components/smartthings/conftest.py index ecab269c1a2..8588c81654e 100644 --- a/tests/components/smartthings/conftest.py +++ b/tests/components/smartthings/conftest.py @@ -47,6 +47,7 @@ from homeassistant.setup import async_setup_component from tests.async_mock import Mock, patch from tests.common import MockConfigEntry +from tests.components.light.conftest import mock_light_profiles # noqa COMPONENT_PREFIX = "homeassistant.components.smartthings." diff --git a/tests/components/switch/conftest.py b/tests/components/switch/conftest.py new file mode 100644 index 00000000000..d69757a9b1b --- /dev/null +++ b/tests/components/switch/conftest.py @@ -0,0 +1,2 @@ +"""switch conftest.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/tasmota/conftest.py b/tests/components/tasmota/conftest.py index 09a3bfa4d63..fadf8a44648 100644 --- a/tests/components/tasmota/conftest.py +++ b/tests/components/tasmota/conftest.py @@ -1,5 +1,4 @@ """Test fixtures for Tasmota component.""" - from hatasmota.discovery import get_status_sensor_entities import pytest @@ -17,6 +16,7 @@ from tests.common import ( mock_device_registry, mock_registry, ) +from tests.components.light.conftest import mock_light_profiles # noqa @pytest.fixture diff --git a/tests/components/template/conftest.py b/tests/components/template/conftest.py new file mode 100644 index 00000000000..8e3491b160a --- /dev/null +++ b/tests/components/template/conftest.py @@ -0,0 +1,2 @@ +"""template conftest.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/tplink/conftest.py b/tests/components/tplink/conftest.py new file mode 100644 index 00000000000..d1800513486 --- /dev/null +++ b/tests/components/tplink/conftest.py @@ -0,0 +1,2 @@ +"""tplink conftest.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/tradfri/conftest.py b/tests/components/tradfri/conftest.py index a944f836dea..c95bf2c036c 100644 --- a/tests/components/tradfri/conftest.py +++ b/tests/components/tradfri/conftest.py @@ -4,6 +4,7 @@ import pytest from . import MOCK_GATEWAY_ID from tests.async_mock import Mock, patch +from tests.components.light.conftest import mock_light_profiles # noqa # pylint: disable=protected-access diff --git a/tests/components/vera/conftest.py b/tests/components/vera/conftest.py index 193c0733736..c20dc4ed499 100644 --- a/tests/components/vera/conftest.py +++ b/tests/components/vera/conftest.py @@ -1,10 +1,10 @@ """Fixtures for tests.""" - import pytest from .common import ComponentFactory from tests.async_mock import patch +from tests.components.light.conftest import mock_light_profiles # noqa @pytest.fixture() diff --git a/tests/components/wilight/conftest.py b/tests/components/wilight/conftest.py new file mode 100644 index 00000000000..a8fd13553dd --- /dev/null +++ b/tests/components/wilight/conftest.py @@ -0,0 +1,2 @@ +"""wilight conftest.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/wled/conftest.py b/tests/components/wled/conftest.py new file mode 100644 index 00000000000..31b71a92f19 --- /dev/null +++ b/tests/components/wled/conftest.py @@ -0,0 +1,2 @@ +"""wled conftest.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/yeelight/conftest.py b/tests/components/yeelight/conftest.py new file mode 100644 index 00000000000..3e65a60f374 --- /dev/null +++ b/tests/components/yeelight/conftest.py @@ -0,0 +1,2 @@ +"""yeelight conftest.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/zerproc/conftest.py b/tests/components/zerproc/conftest.py new file mode 100644 index 00000000000..b4c35bebc71 --- /dev/null +++ b/tests/components/zerproc/conftest.py @@ -0,0 +1,2 @@ +"""zerproc conftest.""" +from tests.components.light.conftest import mock_light_profiles # noqa diff --git a/tests/components/zha/conftest.py b/tests/components/zha/conftest.py index a5aa330a813..2a2ea6a1bb0 100644 --- a/tests/components/zha/conftest.py +++ b/tests/components/zha/conftest.py @@ -1,5 +1,4 @@ """Test configuration for the ZHA component.""" - import pytest import zigpy from zigpy.application import ControllerApplication @@ -16,6 +15,7 @@ from .common import FakeDevice, FakeEndpoint, get_zha_gateway from tests.async_mock import AsyncMock, MagicMock, PropertyMock, patch from tests.common import MockConfigEntry +from tests.components.light.conftest import mock_light_profiles # noqa FIXTURE_GRP_ID = 0x1001 FIXTURE_GRP_NAME = "fixture group" diff --git a/tests/components/zwave/conftest.py b/tests/components/zwave/conftest.py index 146347620bd..5366f028328 100644 --- a/tests/components/zwave/conftest.py +++ b/tests/components/zwave/conftest.py @@ -4,6 +4,7 @@ import pytest from homeassistant.components.zwave import const from tests.async_mock import AsyncMock, MagicMock, patch +from tests.components.light.conftest import mock_light_profiles # noqa from tests.mock.zwave import MockNetwork, MockNode, MockOption, MockValue