Skip to content

WIP: detect old attribute values #76

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions custom_components/pyscript/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,16 +210,49 @@ async def state_changed(event):
else:
new_val = event.data["new_state"].state
old_val = event.data["old_state"].state if event.data["old_state"] else None

if old_val == new_val:
val_change = False
else:
val_change = True

new_vars = {var_name: new_val, f"{var_name}.old": old_val}
func_args = {
"trigger_type": "state",
"var_name": var_name,
"value": new_val,
"old_value": old_val,
"change": val_change,
"context": event.context,
}
await State.update(new_vars, func_args)

if "new_state" not in event.data or event.data["new_state"] is None:
return

for attribute in event.data["new_state"].attributes:
new_val = event.data["new_state"].attributes[attribute]
if "old_state" in event.data and event.data['old_state'] is not None and attribute in event.data["old_state"].attributes:
old_val = event.data["old_state"].attributes[attribute]
else:
old_val = None

if old_val == new_val:
val_change = False
else:
val_change = True

new_vars = {f"{var_name}.{attribute}": new_val, f"{var_name}.old.{attribute}": old_val}
func_args = {
"trigger_type": "state",
"var_name": f"{var_name}.{attribute}",
"value": new_val,
"old_value": old_val,
"change": val_change,
"context": event.context,
}
await State.update(new_vars, func_args)

async def hass_started(event):
_LOGGER.debug("adding state changed listener and starting global contexts")
await State.get_service_params()
Expand Down
2 changes: 1 addition & 1 deletion custom_components/pyscript/eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ async def do_service_call(func, ast_ctx, data):
kwarg_check = {
"task_unique": {"kill_me"},
"time_active": {"hold_off"},
"state_trigger": {"state_hold", "state_check_now"},
"state_trigger": {"state_hold", "state_check_now", "only_on_change"},
}
for dec_name in trig_args:
if dec_name not in kwarg_check and "kwargs" in trig_args[dec_name]:
Expand Down
8 changes: 6 additions & 2 deletions custom_components/pyscript/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,13 @@ async def notify_add(cls, var_names, queue):

for var_name in var_names if isinstance(var_names, set) else {var_names}:
parts = var_name.split(".")
if len(parts) != 2 and len(parts) != 3:
if len(parts) == 2:
state_var_name = f"{parts[0]}.{parts[1]}"
elif len(parts) == 3:
state_var_name = f"{parts[0]}.{parts[1]}.{parts[2]}"
else:
continue
state_var_name = f"{parts[0]}.{parts[1]}"

if state_var_name not in cls.notify:
cls.notify[state_var_name] = {}
cls.notify[state_var_name][queue] = var_names
Expand Down
9 changes: 8 additions & 1 deletion custom_components/pyscript/trigger.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
_LOGGER = logging.getLogger(LOGGER_PATH + ".trigger")


STATE_RE = re.compile(r"[a-zA-Z]\w*\.[a-zA-Z]\w*$")
STATE_RE = re.compile(r"[a-zA-Z]\w*\.[a-zA-Z]\w*(\.[a-zA-Z]\w*)?$")


def dt_now():
Expand Down Expand Up @@ -538,6 +538,7 @@ def __init__(
self.state_trigger_kwargs = trig_cfg.get("state_trigger", {}).get("kwargs", {})
self.state_hold_dur = self.state_trigger_kwargs.get("state_hold", None)
self.state_check_now = self.state_trigger_kwargs.get("state_check_now", False)
self.only_on_change = self.state_trigger_kwargs.get("only_on_change", True)
self.time_trigger = trig_cfg.get("time_trigger", {}).get("args", None)
self.event_trigger = trig_cfg.get("event_trigger", {}).get("args", None)
self.state_active = trig_cfg.get("state_active", {}).get("args", None)
Expand Down Expand Up @@ -785,6 +786,12 @@ async def trigger_watch(self):
else:
func_args = notify_info

#
# check if our value changed and if we want to trigger on non changes
#
if self.only_on_change and "change" in func_args and not func_args['change']:
continue

#
# now check the state and time active expressions
#
Expand Down