Skip to content

Commit

Permalink
[schedy] Deprecated OVERLAY_REVERT_ON_NO_RESULT result marker
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert Schindler committed Sep 10, 2019
1 parent 34359cc commit 2c9cb18
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 36 deletions.
3 changes: 3 additions & 0 deletions docs/apps/schedy/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Changed
* The `Skip` expression result type has been renamed to `Next`, which better describes
its purpose.
* The behaviour of the `OVERLAY_REVERT_ON_NO_RESULT` result marker now is the
default with `OVERLAY`. The marker will be removed.

### Deprecated
* 0.7: The previous name `Skip` for the `Next` expression result type will be removed.
* 0.7: The `OVERLAY_REVERT_ON_NO_RESULT` marker will be removed, it's the default now.

### Removed

Expand Down
12 changes: 6 additions & 6 deletions docs/apps/schedy/schedules/expressions/result-markers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ The following markers are available:
An occasion for using this marker is
:doc:`../../tips-and-tricks/open-window-detection`.

* ``OVERLAY_REVERT_ON_NO_RESULT``: When applied in conjunction with the
``OVERLAY`` marker, the overlay is cancelled as soon as a schedule
evaluation produces no result (e.g. because ``Abort()`` was used). When
an overlay is created without this additional marker, the value marked
with ``OVERLAY`` stays active until the schedule really results in
another value.
* ``OVERLAY_REVERT_ON_NO_RESULT``: When applied in conjunction with the ``OVERLAY``
marker, the overlay is cancelled as soon as a schedule evaluation produces no result
(e.g. because ``Abort()`` was used or all rules evaluated to ``Next()``). When an
overlay is created without this additional marker, the value marked with ``OVERLAY``
stays active until the schedule really results in another value.
**DEPRECATED:** This is the default behaviour of `OVERLAY` now.
58 changes: 28 additions & 30 deletions hass_apps/schedy/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ def __init__(self, name: str, cfg: dict, app: "SchedyApp") -> None:
self._overlaid_wanted_value = None # type: T.Any
self._overlaid_scheduled_value = None # type: T.Any
self._overlaid_rescheduling_time = None # type: T.Optional[datetime.datetime]
self._overlay_revert_on_no_result = None # type: T.Optional[bool]

self._last_state = None # type: T.Optional[T.Tuple[str, T.Dict[str, T.Any]]]

Expand All @@ -100,7 +99,6 @@ def _clear_overlay(self) -> None:
self._overlaid_wanted_value = None
self._overlaid_scheduled_value = None
self._overlaid_rescheduling_time = None
self._overlay_revert_on_no_result = None

@sync_proxy
def _initialize_actor_cb(self, kwargs: dict) -> None:
Expand Down Expand Up @@ -173,7 +171,6 @@ def _deserialize_dt(value: T.Any) -> T.Optional[datetime.datetime]:
self._overlaid_rescheduling_time = _deserialize_dt(
attrs.get("overlaid_rescheduling_time")
)
self._overlay_revert_on_no_result = attrs.get("overlay_revert_on_no_result")

if self._rescheduling_time:
if self._rescheduling_time > self.app.datetime():
Expand Down Expand Up @@ -210,26 +207,25 @@ def _state_entity_id(self) -> str:

return "schedy_room.{}_{}".format(self.app.name, self.name)

def _store_for_overlaying(self, scheduled_value: T.Any) -> bool:
def _store_for_overlaying(self) -> bool:
"""This method is called before a value overlay is put into place.
When a re-scheduling timer is running or the scheduled and
wanted values differ, this method stores the scheduled and wanted
value together with the re-scheduling time to later be able to
re-set it.
Everything except scheduled_value is fetched from self._*.
A running re-scheduling timer is cancelled.
If there already is an overlaid value stored, this does nothing.
Returns whether values have been stored."""

if self._overlaid_wanted_value is None and (
scheduled_value != self._wanted_value or self._rescheduling_timer
self._scheduled_value != self._wanted_value or self._rescheduling_timer
):
self.log(
"Storing currently wanted value {} before an overlay "
"is applied.".format(repr(self._wanted_value))
)
self._overlaid_wanted_value = self._wanted_value
self._overlaid_scheduled_value = scheduled_value
self._overlaid_scheduled_value = self._scheduled_value
self._overlaid_rescheduling_time = self._rescheduling_time
self.cancel_rescheduling_timer()
return True
Expand Down Expand Up @@ -274,7 +270,6 @@ def _maybe_add(key: str, value: T.Any) -> None:
"overlaid_rescheduling_time",
_serialize_dt(self._overlaid_rescheduling_time),
)
_maybe_add("overlay_revert_on_no_result", self._overlay_revert_on_no_result)
_maybe_add("friendly_name", self.cfg.get("friendly_name"))

unchanged = (state, attrs) == self._last_state
Expand Down Expand Up @@ -328,12 +323,19 @@ def _restore_overlaid_value() -> bool:
Returns whether a value has actually been set or not."""

overlaid_wanted_value = self._overlaid_wanted_value
delay = None # type: T.Union[None, datetime.datetime]
if (
self._overlaid_rescheduling_time
and self._overlaid_rescheduling_time > self.app.datetime()
):
if overlaid_wanted_value is None:
return False

delay = None # type: T.Union[None, int, datetime.datetime]
if not self._overlaid_rescheduling_time:
if new_scheduled_value == self._overlaid_scheduled_value:
# scheduled value hasn't changed compared to before overlay,
# hence revert to overlaid value without timer
delay = 0
elif self._overlaid_rescheduling_time > self.app.datetime():
# resume overlaid re-scheduling timer
delay = self._overlaid_rescheduling_time

self._clear_overlay()
if delay is None:
return False
Expand All @@ -355,30 +357,25 @@ def _restore_overlaid_value() -> bool:
result = self.schedule.evaluate(self, self.app.datetime())
if result is None:
self.log("No suitable value found in schedule.", level="DEBUG")
if self._overlay_revert_on_no_result:
self._scheduled_value = self._overlaid_scheduled_value
_restore_overlaid_value()
# revert an eventual overlay
new_scheduled_value = self._overlaid_scheduled_value
_restore_overlaid_value()
return

value, markers = result[:2]
if value == self._scheduled_value and not reset and not force_resend:
new_scheduled_value, markers = result[:2]
if not (new_scheduled_value != self._scheduled_value or reset or force_resend):
self.log("Result didn't change, not setting it again.", level="DEBUG")
return

previous_scheduled_value = self._scheduled_value
self._scheduled_value = value

if reset:
self.cancel_rescheduling_timer()
self._clear_overlay()
elif expression.types.Mark.OVERLAY in markers:
self._store_for_overlaying(previous_scheduled_value)
self._overlay_revert_on_no_result = (
expression.types.Mark.OVERLAY_REVERT_ON_NO_RESULT in markers
)
elif self._overlaid_wanted_value is not None:
if _restore_overlaid_value():
return
# create new or replace existing overlay
self._store_for_overlaying()
# no overlay should be set, hence try to revert an existing one
elif _restore_overlaid_value():
return
elif self._rescheduling_timer:
self.log(
"Not applying the schedule now due to a running "
Expand All @@ -387,7 +384,8 @@ def _restore_overlaid_value() -> bool:
)
return

self.set_value(value, force_resend=force_resend)
self._scheduled_value = new_scheduled_value
self.set_value(new_scheduled_value, force_resend=force_resend)

def cancel_rescheduling_timer(self) -> bool:
"""Cancels the re-scheduling timer for this room, if one
Expand Down Expand Up @@ -640,7 +638,7 @@ def set_value_manually(
return

if expression.types.Mark.OVERLAY in markers:
self._store_for_overlaying(self._scheduled_value)
self._store_for_overlaying()

self.set_value(value, force_resend=force_resend)
if rescheduling_delay != 0:
Expand Down

0 comments on commit 2c9cb18

Please sign in to comment.