|
17 | 17 | from .eval import AstEval
|
18 | 18 | from .event import Event
|
19 | 19 | from .function import Function
|
20 |
| -from .state import State, STATE_VIRTUAL_ATTRS |
| 20 | +from .state import STATE_VIRTUAL_ATTRS, State |
21 | 21 |
|
22 | 22 | _LOGGER = logging.getLogger(LOGGER_PATH + ".trigger")
|
23 | 23 |
|
@@ -49,73 +49,58 @@ def parse_time_offset(offset_str):
|
49 | 49 |
|
50 | 50 |
|
51 | 51 | def ident_any_values_changed(func_args, ident):
|
52 |
| - """Check for changes to state or attributes on ident any vars""" |
53 |
| - value = func_args.get('value') |
54 |
| - old_value = func_args.get('old_value') |
55 |
| - var_name = func_args.get('var_name') |
| 52 | + """Check for any changes to state or attributes on ident vars.""" |
| 53 | + var_name = func_args.get("var_name", None) |
56 | 54 |
|
57 | 55 | if var_name is None:
|
58 | 56 | return False
|
| 57 | + value = func_args["value"] |
| 58 | + old_value = func_args["old_value"] |
59 | 59 |
|
60 | 60 | for check_var in ident:
|
61 | 61 | if check_var == var_name and old_value != value:
|
62 | 62 | return True
|
63 | 63 |
|
64 | 64 | if check_var.startswith(f"{var_name}."):
|
65 |
| - var_pieces = check_var.split('.') |
| 65 | + var_pieces = check_var.split(".") |
66 | 66 | if len(var_pieces) == 3 and f"{var_pieces[0]}.{var_pieces[1]}" == var_name:
|
67 | 67 | if var_pieces[2] == "*":
|
68 | 68 | # catch all has been requested, check all attributes for change
|
69 |
| - all_attributes = set() |
| 69 | + all_attrs = set() |
70 | 70 | if value is not None:
|
71 |
| - all_attributes |= set(value.__dict__.keys()) |
| 71 | + all_attrs |= set(value.__dict__.keys()) |
72 | 72 | if old_value is not None:
|
73 |
| - all_attributes |= set(old_value.__dict__.keys()) |
74 |
| - all_attributes -= STATE_VIRTUAL_ATTRS |
75 |
| - for attribute in all_attributes: |
76 |
| - attrib_val = getattr(value, attribute, None) |
77 |
| - attrib_old_val = getattr(old_value, attribute, None) |
78 |
| - if attrib_old_val != attrib_val: |
| 73 | + all_attrs |= set(old_value.__dict__.keys()) |
| 74 | + for attr in all_attrs - STATE_VIRTUAL_ATTRS: |
| 75 | + if getattr(value, attr, None) != getattr(old_value, attr, None): |
79 | 76 | return True
|
80 |
| - else: |
81 |
| - attrib_val = getattr(value, var_pieces[2], None) |
82 |
| - attrib_old_val = getattr(old_value, var_pieces[2], None) |
83 |
| - if attrib_old_val != attrib_val: |
84 |
| - return True |
85 |
| - |
| 77 | + elif getattr(value, var_pieces[2], None) != getattr(old_value, var_pieces[2], None): |
| 78 | + return True |
| 79 | + |
86 | 80 | return False
|
87 | 81 |
|
| 82 | + |
88 | 83 | def ident_values_changed(func_args, ident):
|
89 |
| - """Check for changes to state or attributes on ident vars""" |
90 |
| - value = func_args.get('value') |
91 |
| - old_value = func_args.get('old_value') |
92 |
| - var_name = func_args.get('var_name') |
| 84 | + """Check for changes to state or attributes on ident vars.""" |
| 85 | + var_name = func_args.get("var_name", None) |
93 | 86 |
|
94 | 87 | if var_name is None:
|
95 | 88 | return False
|
| 89 | + value = func_args["value"] |
| 90 | + old_value = func_args["old_value"] |
96 | 91 |
|
97 | 92 | for check_var in ident:
|
98 |
| - # if check_var in self.state_trig_ident_any: |
99 |
| - # _LOGGER.debug( |
100 |
| - # "%s ident change skipping %s because also ident_any", |
101 |
| - # self.name, |
102 |
| - # check_var, |
103 |
| - # ) |
104 |
| - # continue |
105 |
| - var_pieces = check_var.split('.') |
| 93 | + var_pieces = check_var.split(".") |
106 | 94 | if len(var_pieces) == 2 and check_var == var_name:
|
107 | 95 | if value != old_value:
|
108 | 96 | return True
|
109 | 97 | elif len(var_pieces) == 3 and f"{var_pieces[0]}.{var_pieces[1]}" == var_name:
|
110 |
| - attrib_val = getattr(value, var_pieces[2], None) |
111 |
| - attrib_old_val = getattr(old_value, var_pieces[2], None) |
112 |
| - if attrib_old_val != attrib_val: |
| 98 | + if getattr(value, var_pieces[2], None) != getattr(old_value, var_pieces[2], None): |
113 | 99 | return True
|
114 | 100 |
|
115 | 101 | return False
|
116 | 102 |
|
117 | 103 |
|
118 |
| - |
119 | 104 | class TrigTime:
|
120 | 105 | """Class for trigger time functions."""
|
121 | 106 |
|
@@ -222,7 +207,8 @@ async def wait_until(
|
222 | 207 | #
|
223 | 208 | # check straight away to see if the condition is met (to avoid race conditions)
|
224 | 209 | #
|
225 |
| - state_trig_ok = await state_trig_eval.eval(State.notify_var_get(state_trig_ident, {})) |
| 210 | + new_vars = State.notify_var_get(state_trig_ident, {}) |
| 211 | + state_trig_ok = await state_trig_eval.eval(new_vars) |
226 | 212 | exc = state_trig_eval.get_exception_obj()
|
227 | 213 | if exc is not None:
|
228 | 214 | raise exc
|
@@ -324,8 +310,8 @@ async def wait_until(
|
324 | 310 |
|
325 | 311 | if not ident_any_values_changed(func_args, state_trig_ident_any):
|
326 | 312 | # if var_name not in func_args we are state_check_now
|
327 |
| - if "var_name" in func_args and not ident_values_changed(func_args, state_trig): |
328 |
| - state_trig_ok = False |
| 313 | + if "var_name" in func_args and not ident_values_changed(func_args, state_trig_ident): |
| 314 | + continue |
329 | 315 |
|
330 | 316 | if state_trig_eval:
|
331 | 317 | state_trig_ok = await state_trig_eval.eval(new_vars)
|
@@ -813,7 +799,9 @@ async def trigger_watch(self):
|
813 | 799 |
|
814 | 800 | if not ident_any_values_changed(func_args, self.state_trig_ident_any):
|
815 | 801 | # if var_name not in func_args we are state_check_now
|
816 |
| - if "var_name" in func_args and not ident_values_changed(func_args, self.state_trig_ident): |
| 802 | + if "var_name" in func_args and not ident_values_changed( |
| 803 | + func_args, self.state_trig_ident |
| 804 | + ): |
817 | 805 | continue
|
818 | 806 |
|
819 | 807 | if self.state_trig_eval:
|
@@ -965,8 +953,9 @@ async def do_func_call(func, ast_ctx, task_unique, task_unique_func, hass_contex
|
965 | 953 | except asyncio.CancelledError:
|
966 | 954 | raise
|
967 | 955 |
|
968 |
| - except Exception: |
| 956 | + except Exception as exc: |
969 | 957 | # _LOGGER.error(f"{self.name}: " + traceback.format_exc(-1))
|
| 958 | + _LOGGER.error("%s: %s", self.name, exc) |
970 | 959 | if self.state_trig_ident:
|
971 | 960 | State.notify_del(self.state_trig_ident, self.notify_q)
|
972 | 961 | if self.event_trigger is not None:
|
|
0 commit comments