rename 'manually_controlled' -> 'manual_control' and fix state save bug

This commit is contained in:
Bas Nijholt 2020-10-16 14:14:44 +02:00
commit d3861163d7
3 changed files with 41 additions and 41 deletions

View file

@ -40,8 +40,8 @@ ATTR_TURN_ON_OFF_LISTENER = "turn_on_off_listener"
UNDO_UPDATE_LISTENER = "undo_update_listener"
NONE_STR = "None"
SERVICE_SET_MANUALLY_CONTROLLED = "set_manually_controlled"
CONF_MANUALLY_CONTROLLED = "manually_controlled"
SERVICE_SET_MANUAL_CONTROL = "set_manual_control"
CONF_MANUAL_CONTROL = "manual_control"
SERVICE_APPLY = "apply"
CONF_TURN_ON_LIGHTS = "turn_on_lights"

View file

@ -22,14 +22,14 @@ apply:
turn_on_lights:
description: "Turn on the lights that are off, default: false"
example: false
set_manually_controlled:
description: Mark a light as (not) being 'manually_controlled'.
set_manual_control:
description: Mark whether a light is 'manually controlled'.
fields:
entity_id:
description: entity_id of the Adaptive Lighting switch.
example: switch.adaptive_lighting_default
manually_controlled:
description: "Whether to add ('true') or remove ('false') the light from the 'manually_controlled' list, default: true"
manual_control:
description: "Whether to add ('true') or remove ('false') the light from the 'manual_control' list, default: true"
example: true
lights:
description: entity_id(s) of lights.

View file

@ -85,7 +85,7 @@ from .const import (
CONF_INITIAL_TRANSITION,
CONF_INTERVAL,
CONF_LIGHTS,
CONF_MANUALLY_CONTROLLED,
CONF_MANUAL_CONTROL,
CONF_MAX_BRIGHTNESS,
CONF_MAX_COLOR_TEMP,
CONF_MIN_BRIGHTNESS,
@ -105,7 +105,7 @@ from .const import (
EXTRA_VALIDATION,
ICON,
SERVICE_APPLY,
SERVICE_SET_MANUALLY_CONTROLLED,
SERVICE_SET_MANUAL_CONTROL,
SUN_EVENT_MIDNIGHT,
SUN_EVENT_NOON,
TURNING_OFF_DELAY,
@ -177,18 +177,16 @@ async def handle_apply(switch: AdaptiveSwitch, service_call: ServiceCall):
)
async def handle_set_manually_controlled(
switch: AdaptiveSwitch, service_call: ServiceCall
):
"""Remove lights from the 'manually_controlled' list."""
async def handle_set_manual_control(switch: AdaptiveSwitch, service_call: ServiceCall):
"""Set or unset lights as 'manually controlled'."""
all_lights = _expand_light_groups(switch.hass, service_call.data[CONF_LIGHTS])
_LOGGER.debug(
"Called 'adaptive_lighting.set_manually_controlled' service with '%s'",
"Called 'adaptive_lighting.set_manual_control' service with '%s'",
service_call.data,
)
if service_call.data[CONF_MANUALLY_CONTROLLED]:
if service_call.data[CONF_MANUAL_CONTROL]:
for light in all_lights:
switch.turn_on_off_listener.manually_controlled[light] = True
switch.turn_on_off_listener.manual_control[light] = True
_fire_manual_control_event(switch.hass, light, service_call.context)
else:
switch.turn_on_off_listener.reset(*all_lights)
@ -205,10 +203,8 @@ async def handle_set_manually_controlled(
def _fire_manual_control_event(
hass: HomeAssistant, light: str, context: Context, is_async=True
):
"""Fire an event that 'light' is marked as manually_controlled."""
"""Fire an event that 'light' is marked as manual_control."""
fire = hass.bus.async_fire if is_async else hass.bus.fire
# Calling the event_type='manually_controlled' would be better, but
# event_type has a 32 character limit.
fire(f"{DOMAIN}.manual_control", {ATTR_ENTITY_ID: light}, context=context)
@ -249,12 +245,12 @@ async def async_setup_entry(
)
platform.async_register_entity_service(
SERVICE_SET_MANUALLY_CONTROLLED,
SERVICE_SET_MANUAL_CONTROL,
{
vol.Required(CONF_LIGHTS): cv.entity_ids,
vol.Optional(CONF_MANUALLY_CONTROLLED, default=True): cv.boolean,
vol.Optional(CONF_MANUAL_CONTROL, default=True): cv.boolean,
},
handle_set_manually_controlled,
handle_set_manual_control,
)
@ -564,12 +560,12 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
"""Return the attributes of the switch."""
if not self.is_on:
return {key: None for key in self._settings}
manually_controlled = [
manual_control = [
light
for light in self._lights
if self.turn_on_off_listener.manually_controlled.get(light)
if self.turn_on_off_listener.manual_control.get(light)
]
return dict(self._settings, manually_controlled=manually_controlled)
return dict(self._settings, manual_control=manual_control)
def create_context(self, which: str = "default") -> Context:
"""Create a context that identifies this Adaptive Lighting instance."""
@ -778,7 +774,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
entity_id,
event.context.id,
)
self.turn_on_off_listener.reset(entity_id, reset_manually_controlled=False)
self.turn_on_off_listener.reset(entity_id, reset_manual_control=False)
# Tracks 'off' → 'on' state changes
self._off_to_on_event[entity_id] = event
lock = self._locks.get(entity_id)
@ -1018,7 +1014,7 @@ class TurnOnOffListener:
# Keep 'asyncio.sleep' tasks that can be cancelled by 'light.turn_on' events
self.sleep_tasks: Dict[str, asyncio.Task] = {}
# Tracks which lights are manually controlled
self.manually_controlled: Dict[str, bool] = {}
self.manual_control: Dict[str, bool] = {}
# Counts the number of times (in a row) a light had a changed state.
self.cnt_significant_changes: Dict[str, int] = defaultdict(int)
# Track 'state_changed' events of self.lights resulting from this integration
@ -1037,11 +1033,11 @@ class TurnOnOffListener:
EVENT_STATE_CHANGED, self.state_changed_event_listener
)
def reset(self, *lights, reset_manually_controlled=True) -> None:
"""Reset the 'manually_controlled' status of the lights."""
def reset(self, *lights, reset_manual_control=True) -> None:
"""Reset the 'manual_control' status of the lights."""
for light in lights:
if reset_manually_controlled:
self.manually_controlled[light] = False
if reset_manual_control:
self.manual_control[light] = False
self.last_state_change.pop(light, None)
self.last_service_data.pop(light, None)
self.cnt_significant_changes[light] = 0
@ -1062,9 +1058,10 @@ class TurnOnOffListener:
if service == SERVICE_TURN_OFF:
transition = service_data.get(ATTR_TRANSITION)
_LOGGER.debug(
"Detected an 'light.turn_off('%s', transition=%s)' event",
"Detected an 'light.turn_off('%s', transition=%s)' event with context.id='%s'",
entity_ids,
transition,
event.context.id,
)
for eid in entity_ids:
self.turn_off_event[eid] = event
@ -1114,9 +1111,10 @@ class TurnOnOffListener:
# incorrect 'min_mireds' and 'max_mireds', which happens e.g., for
# Philips Hue White GU10 Bluetooth lights).
old_state: Optional[List[State]] = self.last_state_change.get(entity_id)
if old_state is None:
self.last_state_change[entity_id] = [new_state]
elif old_state[0].context.id == new_state.context.id:
if (
old_state is not None
and old_state[0].context.id == new_state.context.id
):
# If there is already a state change event from this event (with this
# context) then append it to the already existing list.
_LOGGER.debug(
@ -1126,15 +1124,17 @@ class TurnOnOffListener:
new_state.context.id,
)
self.last_state_change[entity_id].append(new_state)
else:
self.last_state_change[entity_id] = [new_state]
def is_manually_controlled(
self,
light: str,
force: bool,
) -> bool:
"""Check if the light has been 'on' and is now manually being adjusted."""
manually_controlled = self.manually_controlled.setdefault(light, False)
if manually_controlled:
"""Check if the light has been 'on' and is now manually controlled."""
manual_control = self.manual_control.setdefault(light, False)
if manual_control:
# Manually controlled until light is turned on and off
return True
@ -1146,7 +1146,7 @@ class TurnOnOffListener:
):
# Light was already on and 'light.turn_on' was not called by
# the adaptive_lighting integration.
manually_controlled = self.manually_controlled[light] = True
manual_control = self.manual_control[light] = True
_fire_manual_control_event(self.hass, light, turn_on_event.context)
_LOGGER.debug(
"'%s' was already on and 'light.turn_on' was not called by the"
@ -1156,7 +1156,7 @@ class TurnOnOffListener:
light,
turn_on_event.context.id,
)
return manually_controlled
return manual_control
async def significant_change(
self,
@ -1170,7 +1170,7 @@ class TurnOnOffListener:
This method will detect changes that were made to the light without
calling 'light.turn_on', so outside of Home Assistant. If a change is
detected, we mark the light as 'manually_controlled' until the light
detected, we mark the light as 'manually controlled' until the light
or switch is turned 'off' and 'on' again.
"""
if light not in self.last_state_change:
@ -1225,7 +1225,7 @@ class TurnOnOffListener:
# Only mark a light as significantly changing, if changed==True
# N times in a row. We do this because sometimes a state changes
# happens only *after* a new update interval has already started.
self.manually_controlled[light] = True
self.manual_control[light] = True
_fire_manual_control_event(self.hass, light, context, is_async=False)
else:
if n_changes > 1: