mirror of
https://github.com/basnijholt/adaptive-lighting.git
synced 2026-09-14 07:44:04 +02:00
Squashed commit of the following:
commit8dd1b5660eMerge:3b3f56fa888afdAuthor: Benjamin Auquite <halomastar@gmail.com> Date: Mon Apr 10 12:51:11 2023 -0500 merge origin commit3b3f56f2d2Author: Benjamin Auquite <halomastar@gmail.com> Date: Mon Apr 10 12:39:26 2023 -0500 Update test_switch.py commit258964d97bAuthor: Benjamin Auquite <halomastar@gmail.com> Date: Mon Apr 10 12:07:18 2023 -0500 pass flake8 move stuff out of `async_setup_entry` commit5b6ad02e1dMerge:251babcfe7bdd3Author: Benjamin Auquite <halomastar@gmail.com> Date: Sat Apr 8 06:01:44 2023 -0500 Merge branch 'main' into new-service-calls commit251babce9dAuthor: Benjamin Auquite <halomastar@gmail.com> Date: Sat Apr 8 05:35:16 2023 -0500 fixes and now passes tests commitd9cd74bef3Author: Benjamin Auquite <halomastar@gmail.com> Date: Sat Apr 8 05:15:17 2023 -0500 initial commit, passes most tests. 'function too complex'
This commit is contained in:
parent
a888afd6dc
commit
b6790b14eb
3 changed files with 267 additions and 63 deletions
|
|
@ -1,7 +1,12 @@
|
|||
"""Constants for the Adaptive Lighting integration."""
|
||||
|
||||
from homeassistant.components.light import VALID_TRANSITION
|
||||
from homeassistant.const import CONF_ENTITY_ID
|
||||
from homeassistant.const import (
|
||||
CONF_ENTITY_ID,
|
||||
SERVICE_TOGGLE,
|
||||
SERVICE_TURN_OFF,
|
||||
SERVICE_TURN_ON,
|
||||
)
|
||||
from homeassistant.helpers import selector
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
import voluptuous as vol
|
||||
|
|
@ -201,6 +206,19 @@ DOCS[CONF_USE_DEFAULTS] = (
|
|||
'documented defaults), or "configuration" (reverts to switch config defaults). ⚙️'
|
||||
)
|
||||
|
||||
CONF_WHICH_SWITCH, DEFAULT_WHICH_SWITCH = "switch_type", "main"
|
||||
DOCS[CONF_WHICH_SWITCH] = (
|
||||
"Which switch to target in this service call. Options: "
|
||||
'"main" (default, targets the main switch), "sleep", "brightness", "color"'
|
||||
)
|
||||
DOCS[
|
||||
SERVICE_TURN_ON
|
||||
] = "Turn on an Adaptive Lighting main/sleep/brightness/color switch"
|
||||
DOCS[
|
||||
SERVICE_TURN_OFF
|
||||
] = "Turn off an Adaptive Lighting main/sleep/brightness/color switch"
|
||||
DOCS[SERVICE_TOGGLE] = "Toggle an Adaptive Lighting main/sleep/brightness/color switch"
|
||||
|
||||
TURNING_OFF_DELAY = 5
|
||||
|
||||
DOCS_MANUAL_CONTROL = {
|
||||
|
|
@ -341,6 +359,14 @@ def apply_service_schema(initial_transition: int = 1):
|
|||
)
|
||||
|
||||
|
||||
SERVICE_TOGGLE_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_ENTITY_ID): cv.entity_ids,
|
||||
vol.Optional(CONF_LIGHTS, default=[]): cv.entity_ids,
|
||||
vol.Optional(CONF_WHICH_SWITCH): cv.string,
|
||||
}
|
||||
)
|
||||
|
||||
SET_MANUAL_CONTROL_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_ENTITY_ID): cv.entity_ids,
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ from homeassistant.const import (
|
|||
EVENT_CALL_SERVICE,
|
||||
EVENT_HOMEASSISTANT_STARTED,
|
||||
EVENT_STATE_CHANGED,
|
||||
SERVICE_TOGGLE,
|
||||
SERVICE_TURN_OFF,
|
||||
SERVICE_TURN_ON,
|
||||
STATE_OFF,
|
||||
|
|
@ -74,6 +75,7 @@ from homeassistant.core import (
|
|||
HomeAssistant,
|
||||
ServiceCall,
|
||||
State,
|
||||
async_get_hass,
|
||||
callback,
|
||||
)
|
||||
from homeassistant.helpers import entity_platform, entity_registry
|
||||
|
|
@ -134,6 +136,7 @@ from .const import (
|
|||
CONF_TRANSITION,
|
||||
CONF_TURN_ON_LIGHTS,
|
||||
CONF_USE_DEFAULTS,
|
||||
CONF_WHICH_SWITCH,
|
||||
CONST_COLOR,
|
||||
DOMAIN,
|
||||
EXTRA_VALIDATION,
|
||||
|
|
@ -144,6 +147,7 @@ from .const import (
|
|||
SERVICE_APPLY,
|
||||
SERVICE_CHANGE_SWITCH_SETTINGS,
|
||||
SERVICE_SET_MANUAL_CONTROL,
|
||||
SERVICE_TOGGLE_SCHEMA,
|
||||
SET_MANUAL_CONTROL_SCHEMA,
|
||||
SLEEP_MODE_SWITCH,
|
||||
SUN_EVENT_MIDNIGHT,
|
||||
|
|
@ -428,6 +432,139 @@ async def handle_change_switch_settings(
|
|||
)
|
||||
|
||||
|
||||
@callback
|
||||
async def handle_turn_on(service_call: ServiceCall):
|
||||
"""Toggles the specified switch."""
|
||||
hass = async_get_hass()
|
||||
data = service_call.data
|
||||
_LOGGER.debug(
|
||||
"Called 'adaptive_lighting.turn_on' service with '%s'",
|
||||
data,
|
||||
)
|
||||
switches = _get_switches_from_service_call(hass, service_call)
|
||||
if data[CONF_WHICH_SWITCH] == "sleep":
|
||||
switches = [s.sleep_mode_switch for s in switches]
|
||||
elif data[CONF_WHICH_SWITCH] == "brightness":
|
||||
switches = [s.adapt_brightness_switch for s in switches]
|
||||
elif data[CONF_WHICH_SWITCH] == "color":
|
||||
switches = [s.adapt_color_switch for s in switches]
|
||||
|
||||
_LOGGER.debug("Turning on switches [%s]", switches)
|
||||
for switch in switches:
|
||||
await switch.async_turn_on()
|
||||
|
||||
|
||||
@callback
|
||||
async def handle_turn_off(service_call: ServiceCall):
|
||||
"""Toggles the specified switch."""
|
||||
hass = async_get_hass()
|
||||
data = service_call.data
|
||||
_LOGGER.debug(
|
||||
"Called 'adaptive_lighting.turn_off' service with '%s'",
|
||||
data,
|
||||
)
|
||||
switches = _get_switches_from_service_call(hass, service_call)
|
||||
if data[CONF_WHICH_SWITCH] == "sleep":
|
||||
switches = [s.sleep_mode_switch for s in switches]
|
||||
elif data[CONF_WHICH_SWITCH] == "brightness":
|
||||
switches = [s.adapt_brightness_switch for s in switches]
|
||||
elif data[CONF_WHICH_SWITCH] == "color":
|
||||
switches = [s.adapt_color_switch for s in switches]
|
||||
_LOGGER.debug("Turning off switches [%s]", switches)
|
||||
for switch in switches:
|
||||
await switch.async_turn_off()
|
||||
|
||||
|
||||
@callback
|
||||
async def handle_toggle(service_call: ServiceCall):
|
||||
"""Toggles the specified switch."""
|
||||
hass = async_get_hass()
|
||||
data = service_call.data
|
||||
_LOGGER.debug(
|
||||
"Called 'adaptive_lighting.toggle' service with '%s'",
|
||||
data,
|
||||
)
|
||||
switches = _get_switches_from_service_call(hass, service_call)
|
||||
if data[CONF_WHICH_SWITCH] == "sleep":
|
||||
switches = [s.sleep_mode_switch for s in switches]
|
||||
elif data[CONF_WHICH_SWITCH] == "brightness":
|
||||
switches = [s.adapt_brightness_switch for s in switches]
|
||||
elif data[CONF_WHICH_SWITCH] == "color":
|
||||
switches = [s.adapt_color_switch for s in switches]
|
||||
_LOGGER.debug("Toggling switches [%s]", switches)
|
||||
for switch in switches:
|
||||
if switch.is_on:
|
||||
await switch.async_turn_off()
|
||||
else:
|
||||
await switch.async_turn_on()
|
||||
|
||||
|
||||
@callback
|
||||
async def handle_apply(service_call: ServiceCall):
|
||||
"""Handle the entity service apply."""
|
||||
hass = async_get_hass()
|
||||
data = service_call.data
|
||||
_LOGGER.debug(
|
||||
"Called 'adaptive_lighting.apply' service with '%s'",
|
||||
data,
|
||||
)
|
||||
switches = _get_switches_from_service_call(hass, service_call)
|
||||
lights = data[CONF_LIGHTS]
|
||||
for switch in switches:
|
||||
if not lights:
|
||||
all_lights = switch._lights # pylint: disable=protected-access
|
||||
else:
|
||||
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
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@callback
|
||||
async def handle_set_manual_control(service_call: ServiceCall):
|
||||
"""Set or unset lights as 'manually controlled'."""
|
||||
hass = async_get_hass()
|
||||
data = service_call.data
|
||||
_LOGGER.debug(
|
||||
"Called 'adaptive_lighting.set_manual_control' service with '%s'",
|
||||
data,
|
||||
)
|
||||
switches = _get_switches_from_service_call(hass, service_call)
|
||||
lights = data[CONF_LIGHTS]
|
||||
for switch in switches:
|
||||
if not lights:
|
||||
all_lights = switch._lights # pylint: disable=protected-access
|
||||
else:
|
||||
all_lights = _expand_light_groups(switch.hass, lights)
|
||||
if service_call.data[CONF_MANUAL_CONTROL]:
|
||||
for light in all_lights:
|
||||
switch.turn_on_off_listener.mark_as_manual_control(light)
|
||||
_fire_manual_control_event(switch, light, service_call.context)
|
||||
else:
|
||||
switch.turn_on_off_listener.reset(*all_lights)
|
||||
if switch.is_on:
|
||||
# pylint: disable=protected-access
|
||||
await switch._update_attrs_and_maybe_adapt_lights(
|
||||
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,67 +626,6 @@ async def async_setup_entry(
|
|||
update_before_add=True,
|
||||
)
|
||||
|
||||
@callback
|
||||
async def handle_apply(service_call: ServiceCall):
|
||||
"""Handle the entity service apply."""
|
||||
data = service_call.data
|
||||
_LOGGER.debug(
|
||||
"Called 'adaptive_lighting.apply' service with '%s'",
|
||||
data,
|
||||
)
|
||||
switches = _get_switches_from_service_call(hass, service_call)
|
||||
lights = data[CONF_LIGHTS]
|
||||
for switch in switches:
|
||||
if not lights:
|
||||
all_lights = switch._lights # pylint: disable=protected-access
|
||||
else:
|
||||
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
|
||||
),
|
||||
)
|
||||
|
||||
@callback
|
||||
async def handle_set_manual_control(service_call: ServiceCall):
|
||||
"""Set or unset lights as 'manually controlled'."""
|
||||
data = service_call.data
|
||||
_LOGGER.debug(
|
||||
"Called 'adaptive_lighting.set_manual_control' service with '%s'",
|
||||
data,
|
||||
)
|
||||
switches = _get_switches_from_service_call(hass, service_call)
|
||||
lights = data[CONF_LIGHTS]
|
||||
for switch in switches:
|
||||
if not lights:
|
||||
all_lights = switch._lights # pylint: disable=protected-access
|
||||
else:
|
||||
all_lights = _expand_light_groups(switch.hass, lights)
|
||||
if service_call.data[CONF_MANUAL_CONTROL]:
|
||||
for light in all_lights:
|
||||
_fire_manual_control_event(switch, light, service_call.context)
|
||||
else:
|
||||
switch.turn_on_off_listener.reset(*all_lights)
|
||||
if switch.is_on:
|
||||
# pylint: disable=protected-access
|
||||
await switch._update_attrs_and_maybe_adapt_lights(
|
||||
all_lights,
|
||||
transition=switch._initial_transition,
|
||||
force=True,
|
||||
context=switch.create_context(
|
||||
"service", parent=service_call.context
|
||||
),
|
||||
)
|
||||
|
||||
# Register `apply` service
|
||||
hass.services.async_register(
|
||||
domain=DOMAIN,
|
||||
|
|
@ -560,6 +636,30 @@ async def async_setup_entry(
|
|||
), # pylint: disable=protected-access
|
||||
)
|
||||
|
||||
# Register `turn_on` service
|
||||
hass.services.async_register(
|
||||
domain=DOMAIN,
|
||||
service=SERVICE_TURN_ON,
|
||||
service_func=handle_turn_on,
|
||||
schema=SERVICE_TOGGLE_SCHEMA,
|
||||
)
|
||||
|
||||
# Register `turn_off` service
|
||||
hass.services.async_register(
|
||||
domain=DOMAIN,
|
||||
service=SERVICE_TURN_OFF,
|
||||
service_func=handle_turn_off,
|
||||
schema=SERVICE_TOGGLE_SCHEMA,
|
||||
)
|
||||
|
||||
# Register `toggle` service
|
||||
hass.services.async_register(
|
||||
domain=DOMAIN,
|
||||
service=SERVICE_TOGGLE,
|
||||
service_func=handle_toggle,
|
||||
schema=SERVICE_TOGGLE_SCHEMA,
|
||||
)
|
||||
|
||||
# Register `set_manual_control` service
|
||||
hass.services.async_register(
|
||||
domain=DOMAIN,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ from homeassistant.components.adaptive_lighting.const import (
|
|||
CONF_TRANSITION,
|
||||
CONF_TURN_ON_LIGHTS,
|
||||
CONF_USE_DEFAULTS,
|
||||
CONF_WHICH_SWITCH,
|
||||
DEFAULT_MAX_BRIGHTNESS,
|
||||
DEFAULT_NAME,
|
||||
DEFAULT_SLEEP_BRIGHTNESS,
|
||||
|
|
@ -52,7 +53,6 @@ from homeassistant.components.light import (
|
|||
ATTR_XY_COLOR,
|
||||
)
|
||||
from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
|
||||
from homeassistant.components.light import SERVICE_TURN_OFF
|
||||
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
||||
import homeassistant.config as config_util
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
|
|
@ -64,6 +64,8 @@ from homeassistant.const import (
|
|||
CONF_NAME,
|
||||
CONF_PLATFORM,
|
||||
EVENT_STATE_CHANGED,
|
||||
SERVICE_TOGGLE,
|
||||
SERVICE_TURN_OFF,
|
||||
SERVICE_TURN_ON,
|
||||
STATE_OFF,
|
||||
STATE_ON,
|
||||
|
|
@ -1252,6 +1254,82 @@ async def test_area(hass):
|
|||
assert light.entity_id not in switch.turn_on_off_listener.last_service_data
|
||||
|
||||
|
||||
@pytest.mark.dependency(depends=GLOBAL_TEST_DEPENDENCIES)
|
||||
async def test_switch_turn_on_off_toggle(hass):
|
||||
"""Test adaptive_lighting.change_switch_settings service."""
|
||||
switch, (_, _, light) = await setup_lights_and_switch(hass)
|
||||
entity_id = switch.entity_id
|
||||
assert entity_id not in switch._lights
|
||||
|
||||
async def turn_on(which: str, **kwargs):
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{
|
||||
ATTR_ENTITY_ID: entity_id,
|
||||
CONF_WHICH_SWITCH: which,
|
||||
**kwargs,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
async def turn_off(which: str, **kwargs):
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_TURN_OFF,
|
||||
{
|
||||
ATTR_ENTITY_ID: entity_id,
|
||||
CONF_WHICH_SWITCH: which,
|
||||
**kwargs,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
async def toggle(which: str, **kwargs):
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_TOGGLE,
|
||||
{
|
||||
ATTR_ENTITY_ID: entity_id,
|
||||
CONF_WHICH_SWITCH: which,
|
||||
**kwargs,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Test sleep
|
||||
await turn_on("sleep")
|
||||
assert switch.sleep_mode_switch.is_on
|
||||
await turn_off("sleep")
|
||||
assert not switch.sleep_mode_switch.is_on
|
||||
await toggle("sleep")
|
||||
assert switch.sleep_mode_switch.is_on
|
||||
# Test brightness
|
||||
await turn_on("brightness")
|
||||
assert switch.adapt_brightness_switch.is_on
|
||||
await turn_off("brightness")
|
||||
assert not switch.adapt_brightness_switch.is_on
|
||||
await toggle("brightness")
|
||||
assert switch.adapt_brightness_switch.is_on
|
||||
# Test color
|
||||
await turn_on("color")
|
||||
assert switch.adapt_color_switch.is_on
|
||||
await turn_off("color")
|
||||
assert not switch.adapt_color_switch.is_on
|
||||
await toggle("color")
|
||||
assert switch.adapt_color_switch.is_on
|
||||
# Test main
|
||||
await turn_on("main")
|
||||
assert switch.is_on
|
||||
await turn_off("main")
|
||||
assert not switch.is_on
|
||||
await toggle("main")
|
||||
assert switch.is_on
|
||||
|
||||
|
||||
@pytest.mark.dependency(depends=GLOBAL_TEST_DEPENDENCIES)
|
||||
async def test_change_switch_settings_service(hass):
|
||||
"""Test adaptive_lighting.change_switch_settings service."""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue