Squashed commit of the following:

commit 8dd1b5660e
Merge: 3b3f56f a888afd
Author: Benjamin Auquite <halomastar@gmail.com>
Date:   Mon Apr 10 12:51:11 2023 -0500

    merge origin

commit 3b3f56f2d2
Author: Benjamin Auquite <halomastar@gmail.com>
Date:   Mon Apr 10 12:39:26 2023 -0500

    Update test_switch.py

commit 258964d97b
Author: Benjamin Auquite <halomastar@gmail.com>
Date:   Mon Apr 10 12:07:18 2023 -0500

    pass flake8

    move stuff out of `async_setup_entry`

commit 5b6ad02e1d
Merge: 251babc fe7bdd3
Author: Benjamin Auquite <halomastar@gmail.com>
Date:   Sat Apr 8 06:01:44 2023 -0500

    Merge branch 'main' into new-service-calls

commit 251babce9d
Author: Benjamin Auquite <halomastar@gmail.com>
Date:   Sat Apr 8 05:35:16 2023 -0500

    fixes and now passes tests

commit d9cd74bef3
Author: 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:
Benjamin Auquite 2023-04-11 19:07:48 -05:00
commit b6790b14eb
3 changed files with 267 additions and 63 deletions

View file

@ -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,

View file

@ -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,