mirror of
https://github.com/basnijholt/adaptive-lighting.git
synced 2026-09-12 23:04:03 +02:00
passes pytest fails pre-commit
custom_components/adaptive_lighting/switch.py:393:1: C901 'async_setup_entry' is too complex (22)
This commit is contained in:
parent
fe7bdd3940
commit
2ec2912115
3 changed files with 141 additions and 110 deletions
|
|
@ -196,9 +196,9 @@ DOCS[CONF_TURN_ON_LIGHTS] = "Whether to turn on lights that are currently off.
|
|||
SERVICE_CHANGE_SWITCH_SETTINGS = "change_switch_settings"
|
||||
CONF_USE_DEFAULTS = "use_defaults"
|
||||
DOCS[CONF_USE_DEFAULTS] = (
|
||||
"Sets the default values not specified in this service call. Options: "
|
||||
"Where to autofill config options that are not passed to this service. Options: "
|
||||
'"current" (default, retains current values), "factory" (resets to '
|
||||
'documented defaults), or "configuration" (reverts to switch config defaults). ⚙️'
|
||||
'documented defaults), or "configuration" (reverts to original user config). ⚙️'
|
||||
)
|
||||
|
||||
TURNING_OFF_DELAY = 5
|
||||
|
|
@ -321,28 +321,36 @@ _DOMAIN_SCHEMA = vol.Schema(
|
|||
)
|
||||
|
||||
|
||||
def apply_service_schema(initial_transition: int = 1):
|
||||
"""Return the schema for the apply service."""
|
||||
return vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_ENTITY_ID): cv.entity_ids,
|
||||
vol.Optional(CONF_LIGHTS, default=[]): cv.entity_ids,
|
||||
vol.Optional(
|
||||
CONF_TRANSITION,
|
||||
default=initial_transition,
|
||||
): VALID_TRANSITION,
|
||||
vol.Optional(ATTR_ADAPT_BRIGHTNESS, default=True): cv.boolean,
|
||||
vol.Optional(ATTR_ADAPT_COLOR, default=True): cv.boolean,
|
||||
vol.Optional(CONF_PREFER_RGB_COLOR, default=False): cv.boolean,
|
||||
vol.Optional(CONF_TURN_ON_LIGHTS, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
SCHEMA_APPLY = vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_ENTITY_ID): cv.entity_ids,
|
||||
vol.Optional(CONF_LIGHTS, default=[]): cv.entity_ids,
|
||||
vol.Optional(CONF_TRANSITION): VALID_TRANSITION,
|
||||
vol.Optional(ATTR_ADAPT_BRIGHTNESS, default=True): cv.boolean,
|
||||
vol.Optional(ATTR_ADAPT_COLOR, default=True): cv.boolean,
|
||||
vol.Optional(CONF_PREFER_RGB_COLOR, default=False): cv.boolean,
|
||||
vol.Optional(CONF_TURN_ON_LIGHTS, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
SET_MANUAL_CONTROL_SCHEMA = vol.Schema(
|
||||
SCHEMA_SET_MANUAL_CONTROL = vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_ENTITY_ID): cv.entity_ids,
|
||||
vol.Optional(CONF_LIGHTS, default=[]): cv.entity_ids,
|
||||
vol.Optional(CONF_MANUAL_CONTROL, default=True): cv.boolean,
|
||||
}
|
||||
)
|
||||
|
||||
SCHEMA_CHANGE_SWITCH_SETTINGS = vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_USE_DEFAULTS): cv.string,
|
||||
vol.Optional(CONF_ENTITY_ID): cv.entity_ids,
|
||||
vol.Required(CONF_LIGHTS, default=[]): [],
|
||||
**{
|
||||
vol.Optional(k): valid
|
||||
for k, _, valid in VALIDATION_TUPLES
|
||||
if k not in [CONF_INTERVAL, CONF_NAME, CONF_LIGHTS]
|
||||
},
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ from homeassistant.core import (
|
|||
State,
|
||||
callback,
|
||||
)
|
||||
from homeassistant.helpers import entity_platform, entity_registry
|
||||
from homeassistant.helpers import entity_registry
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.event import (
|
||||
async_track_state_change_event,
|
||||
|
|
@ -89,7 +89,6 @@ from homeassistant.util.color import (
|
|||
)
|
||||
import homeassistant.util.dt as dt_util
|
||||
import ulid_transform
|
||||
import voluptuous as vol
|
||||
|
||||
from .const import (
|
||||
ADAPT_BRIGHTNESS_SWITCH,
|
||||
|
|
@ -135,16 +134,17 @@ from .const import (
|
|||
ICON_COLOR_TEMP,
|
||||
ICON_MAIN,
|
||||
ICON_SLEEP,
|
||||
SCHEMA_APPLY,
|
||||
SCHEMA_CHANGE_SWITCH_SETTINGS,
|
||||
SCHEMA_SET_MANUAL_CONTROL,
|
||||
SERVICE_APPLY,
|
||||
SERVICE_CHANGE_SWITCH_SETTINGS,
|
||||
SERVICE_SET_MANUAL_CONTROL,
|
||||
SET_MANUAL_CONTROL_SCHEMA,
|
||||
SLEEP_MODE_SWITCH,
|
||||
SUN_EVENT_MIDNIGHT,
|
||||
SUN_EVENT_NOON,
|
||||
TURNING_OFF_DELAY,
|
||||
VALIDATION_TUPLES,
|
||||
apply_service_schema,
|
||||
replace_none_str,
|
||||
)
|
||||
|
||||
|
|
@ -286,9 +286,9 @@ def _split_service_data(service_data, adapt_brightness, adapt_color):
|
|||
|
||||
|
||||
def _get_switches_with_lights(
|
||||
hass: HomeAssistant, lights: list[str]
|
||||
hass: HomeAssistant, lights: list[str] | None = None
|
||||
) -> list[AdaptiveSwitch]:
|
||||
"""Get all switches that control at least one of the lights passed."""
|
||||
"""Get all switches. If lights is defined, return only switches found with these lights."""
|
||||
config_entries = hass.config_entries.async_entries(DOMAIN)
|
||||
data = hass.data[DOMAIN]
|
||||
switches = []
|
||||
|
|
@ -297,10 +297,13 @@ def _get_switches_with_lights(
|
|||
if entry is None: # entry might be disabled and therefore missing
|
||||
continue
|
||||
switch = data[config.entry_id]["instance"]
|
||||
all_check_lights = _expand_light_groups(hass, lights)
|
||||
switch._expand_light_groups()
|
||||
# Check if any of the lights are in the switch's lights
|
||||
if set(switch._lights) & set(all_check_lights):
|
||||
if lights:
|
||||
all_check_lights = _expand_light_groups(hass, lights)
|
||||
switch._expand_light_groups()
|
||||
# Check if any of the lights are in the switch's lights
|
||||
if set(switch._lights) & set(all_check_lights):
|
||||
switches.append(switch)
|
||||
else:
|
||||
switches.append(switch)
|
||||
return switches
|
||||
|
||||
|
|
@ -342,13 +345,7 @@ def _get_switches_from_service_call(
|
|||
switch_entity_ids: list[str] | None = data.get("entity_id")
|
||||
|
||||
if not lights and not switch_entity_ids:
|
||||
raise ValueError(
|
||||
"adaptive-lighting: Neither a switch nor a light was provided in the service call."
|
||||
" If you intend to adapt all lights on all switches, please inform the developers at"
|
||||
" https://github.com/basnijholt/adaptive-lighting about your use case."
|
||||
" Currently, you must pass either an adaptive-lighting switch or the lights to an"
|
||||
" `adaptive_lighting` service call."
|
||||
)
|
||||
return _get_switches_with_lights(hass)
|
||||
|
||||
if switch_entity_ids is not None:
|
||||
if len(switch_entity_ids) > 1 and lights:
|
||||
|
|
@ -374,44 +371,6 @@ def _get_switches_from_service_call(
|
|||
)
|
||||
|
||||
|
||||
async def handle_change_switch_settings(
|
||||
switch: AdaptiveSwitch, service_call: ServiceCall
|
||||
) -> None:
|
||||
"""Allows HASS to change config values via a service call."""
|
||||
data = service_call.data
|
||||
|
||||
which = data.get(CONF_USE_DEFAULTS, "current")
|
||||
if which == "current": # use whatever we're already using.
|
||||
defaults = switch._current_settings # pylint: disable=protected-access
|
||||
elif which == "factory": # use actual defaults listed in the documentation
|
||||
defaults = {key: default for key, default, _ in VALIDATION_TUPLES}
|
||||
elif which == "configuration":
|
||||
# use whatever's in the config flow or configuration.yaml
|
||||
defaults = switch._config_backup # pylint: disable=protected-access
|
||||
else:
|
||||
defaults = None
|
||||
|
||||
switch._set_changeable_settings(
|
||||
data=data,
|
||||
defaults=defaults,
|
||||
)
|
||||
|
||||
_LOGGER.debug(
|
||||
"Called 'adaptive_lighting.change_switch_settings' service with '%s'",
|
||||
data,
|
||||
)
|
||||
|
||||
all_lights = switch._lights # pylint: disable=protected-access
|
||||
switch.turn_on_off_listener.reset(*all_lights, reset_manual_control=False)
|
||||
if switch.is_on:
|
||||
await switch._update_attrs_and_maybe_adapt_lights( # pylint: disable=protected-access
|
||||
all_lights,
|
||||
transition=switch._initial_transition,
|
||||
force=True,
|
||||
context=switch.create_context("service", parent=service_call.context),
|
||||
)
|
||||
|
||||
|
||||
@callback
|
||||
def _fire_manual_control_event(
|
||||
switch: AdaptiveSwitch, light: str, context: Context, is_async=True
|
||||
|
|
@ -489,18 +448,29 @@ async def async_setup_entry(
|
|||
all_lights = _expand_light_groups(switch.hass, lights)
|
||||
switch.turn_on_off_listener.lights.update(all_lights)
|
||||
for light in all_lights:
|
||||
if data[CONF_TURN_ON_LIGHTS] or is_on(hass, light):
|
||||
await switch._adapt_light( # pylint: disable=protected-access
|
||||
light,
|
||||
data[CONF_TRANSITION],
|
||||
data[ATTR_ADAPT_BRIGHTNESS],
|
||||
data[ATTR_ADAPT_COLOR],
|
||||
data[CONF_PREFER_RGB_COLOR],
|
||||
force=True,
|
||||
context=switch.create_context(
|
||||
"service", parent=service_call.context
|
||||
),
|
||||
)
|
||||
transition = data.get(CONF_TRANSITION)
|
||||
if not data[CONF_TURN_ON_LIGHTS]:
|
||||
if not is_on(hass, light):
|
||||
continue
|
||||
if not transition:
|
||||
transition = (
|
||||
switch._transition
|
||||
) # pylint: disable=protected-access
|
||||
elif not transition:
|
||||
transition = (
|
||||
switch._initial_transition
|
||||
) # pylint: disable=protected-access
|
||||
await switch._adapt_light( # pylint: disable=protected-access
|
||||
light,
|
||||
transition,
|
||||
data[ATTR_ADAPT_BRIGHTNESS],
|
||||
data[ATTR_ADAPT_COLOR],
|
||||
data[CONF_PREFER_RGB_COLOR],
|
||||
force=True,
|
||||
context=switch.create_context(
|
||||
"service", parent=service_call.context
|
||||
),
|
||||
)
|
||||
|
||||
@callback
|
||||
async def handle_set_manual_control(service_call: ServiceCall):
|
||||
|
|
@ -534,14 +504,54 @@ async def async_setup_entry(
|
|||
),
|
||||
)
|
||||
|
||||
@callback
|
||||
async def handle_change_switch_settings(service_call: ServiceCall) -> None:
|
||||
"""Allows HASS to change config values via a service call."""
|
||||
data = service_call.data
|
||||
_LOGGER.debug(
|
||||
"Called 'adaptive_lighting.change_switch_settings' service with '%s'",
|
||||
data,
|
||||
)
|
||||
|
||||
switches = _get_switches_from_service_call(hass, service_call)
|
||||
for switch in switches:
|
||||
# which denotes where to autofill blank config options.
|
||||
which = data.get(CONF_USE_DEFAULTS, "current")
|
||||
if which == "current":
|
||||
# use whatever we're already using.
|
||||
defaults = switch._current_settings # pylint: disable=protected-access
|
||||
elif which == "factory":
|
||||
# use actual defaults listed in the documentation
|
||||
defaults = {key: default for key, default, _ in VALIDATION_TUPLES}
|
||||
elif which == "configuration":
|
||||
# use whatever's in the config flow or configuration.yaml
|
||||
defaults = switch._config_backup # pylint: disable=protected-access
|
||||
else:
|
||||
defaults = None
|
||||
|
||||
switch._set_changeable_settings(
|
||||
data=data,
|
||||
defaults=defaults,
|
||||
)
|
||||
|
||||
all_lights = switch._lights # pylint: disable=protected-access
|
||||
switch.turn_on_off_listener.reset(*all_lights, reset_manual_control=False)
|
||||
|
||||
if not switch.is_on:
|
||||
continue
|
||||
await switch._update_attrs_and_maybe_adapt_lights( # pylint: disable=protected-access
|
||||
all_lights,
|
||||
transition=switch._transition,
|
||||
force=True,
|
||||
context=switch.create_context("service", parent=service_call.context),
|
||||
)
|
||||
|
||||
# Register `apply` service
|
||||
hass.services.async_register(
|
||||
domain=DOMAIN,
|
||||
service=SERVICE_APPLY,
|
||||
service_func=handle_apply,
|
||||
schema=apply_service_schema(
|
||||
switch._initial_transition
|
||||
), # pylint: disable=protected-access
|
||||
schema=SCHEMA_APPLY,
|
||||
)
|
||||
|
||||
# Register `set_manual_control` service
|
||||
|
|
@ -549,20 +559,14 @@ async def async_setup_entry(
|
|||
domain=DOMAIN,
|
||||
service=SERVICE_SET_MANUAL_CONTROL,
|
||||
service_func=handle_set_manual_control,
|
||||
schema=SET_MANUAL_CONTROL_SCHEMA,
|
||||
schema=SCHEMA_SET_MANUAL_CONTROL,
|
||||
)
|
||||
|
||||
args = {vol.Optional(CONF_USE_DEFAULTS, default="current"): cv.string}
|
||||
# Modifying these after init isn't possible
|
||||
skip = (CONF_INTERVAL, CONF_NAME, CONF_LIGHTS)
|
||||
for k, _, valid in VALIDATION_TUPLES:
|
||||
if k not in skip:
|
||||
args[vol.Optional(k)] = valid
|
||||
platform = entity_platform.current_platform.get()
|
||||
platform.async_register_entity_service(
|
||||
SERVICE_CHANGE_SWITCH_SETTINGS,
|
||||
args,
|
||||
handle_change_switch_settings,
|
||||
hass.services.async_register(
|
||||
domain=DOMAIN,
|
||||
service=SERVICE_CHANGE_SWITCH_SETTINGS,
|
||||
service_func=handle_change_switch_settings,
|
||||
schema=SCHEMA_CHANGE_SWITCH_SETTINGS,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1256,6 +1256,9 @@ async def test_area(hass):
|
|||
async def test_change_switch_settings_service(hass):
|
||||
"""Test adaptive_lighting.change_switch_settings service."""
|
||||
switch, (_, _, light) = await setup_lights_and_switch(hass)
|
||||
switch2, (_, light2, _) = await setup_lights_and_switch(
|
||||
hass, {CONF_NAME: "second_switch"}
|
||||
)
|
||||
entity_id = light.entity_id
|
||||
assert entity_id not in switch._lights
|
||||
|
||||
|
|
@ -1264,7 +1267,6 @@ async def test_change_switch_settings_service(hass):
|
|||
DOMAIN,
|
||||
SERVICE_CHANGE_SWITCH_SETTINGS,
|
||||
{
|
||||
ATTR_ENTITY_ID: ENTITY_SWITCH,
|
||||
**kwargs,
|
||||
},
|
||||
blocking=True,
|
||||
|
|
@ -1273,12 +1275,16 @@ async def test_change_switch_settings_service(hass):
|
|||
|
||||
# Test changing sunrise offset
|
||||
assert switch._sun_light_settings.sunrise_offset.total_seconds() == 0
|
||||
await change_switch_settings(**{CONF_SUNRISE_OFFSET: 10})
|
||||
await change_switch_settings(
|
||||
**{ATTR_ENTITY_ID: ENTITY_SWITCH, CONF_SUNRISE_OFFSET: 10}
|
||||
)
|
||||
assert switch._sun_light_settings.sunrise_offset.total_seconds() == 10
|
||||
|
||||
# Test changing max brightness
|
||||
assert switch._sun_light_settings.max_brightness == 100
|
||||
await change_switch_settings(**{CONF_MAX_BRIGHTNESS: 50})
|
||||
await change_switch_settings(
|
||||
**{ATTR_ENTITY_ID: ENTITY_SWITCH, CONF_MAX_BRIGHTNESS: 50}
|
||||
)
|
||||
assert switch._sun_light_settings.max_brightness == 50
|
||||
|
||||
# Test changing to illegal max brightness
|
||||
|
|
@ -1286,20 +1292,33 @@ async def test_change_switch_settings_service(hass):
|
|||
voluptuous.error.MultipleInvalid,
|
||||
match="value must be at most 100 for dictionary",
|
||||
):
|
||||
await change_switch_settings(**{CONF_MAX_BRIGHTNESS: 5000})
|
||||
await change_switch_settings(
|
||||
**{ATTR_ENTITY_ID: ENTITY_SWITCH, CONF_MAX_BRIGHTNESS: 5000}
|
||||
)
|
||||
|
||||
# Change CONF_MIN_COLOR_TEMP, the factory default is 2000, but setup_lights_and_switch
|
||||
# sets it to 2500
|
||||
assert switch._sun_light_settings.min_color_temp == 2500
|
||||
|
||||
# testing with "factory" should change it to 2000
|
||||
await change_switch_settings(**{CONF_USE_DEFAULTS: "factory"})
|
||||
await change_switch_settings(
|
||||
**{ATTR_ENTITY_ID: ENTITY_SWITCH, CONF_USE_DEFAULTS: "factory"}
|
||||
)
|
||||
assert switch._sun_light_settings.min_color_temp == 2000
|
||||
|
||||
# testing with "current" should not change things
|
||||
await change_switch_settings(**{CONF_USE_DEFAULTS: "current"})
|
||||
await change_switch_settings(
|
||||
**{ATTR_ENTITY_ID: ENTITY_SWITCH, CONF_USE_DEFAULTS: "current"}
|
||||
)
|
||||
assert switch._sun_light_settings.min_color_temp == 2000
|
||||
|
||||
# testing with "configuration" should revert back to 2500
|
||||
await change_switch_settings(**{CONF_USE_DEFAULTS: "configuration"})
|
||||
await change_switch_settings(
|
||||
**{ATTR_ENTITY_ID: ENTITY_SWITCH, CONF_USE_DEFAULTS: "configuration"}
|
||||
)
|
||||
assert switch._sun_light_settings.min_color_temp == 2500
|
||||
|
||||
# testing with no switches or lights defined.
|
||||
assert switch2._sun_light_settings.max_brightness == 100
|
||||
await change_switch_settings(**{CONF_MAX_BRIGHTNESS: 50})
|
||||
assert switch2._sun_light_settings.max_brightness == 50
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue