|
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