@@ -48,6 +48,74 @@ def parse_time_offset(offset_str):
48
48
return value * scale
49
49
50
50
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' )
56
+
57
+ if var_name is None :
58
+ return False
59
+
60
+ for check_var in ident :
61
+ if check_var == var_name and old_value != value :
62
+ return True
63
+
64
+ if check_var .startswith (f"{ var_name } ." ):
65
+ var_pieces = check_var .split ('.' )
66
+ if len (var_pieces ) == 3 and f"{ var_pieces [0 ]} .{ var_pieces [1 ]} " == var_name :
67
+ if var_pieces [2 ] == "*" :
68
+ # catch all has been requested, check all attributes for change
69
+ all_attributes = set ()
70
+ if value is not None :
71
+ all_attributes |= set (value .__dict__ .keys ())
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 :
79
+ 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
+
86
+ return False
87
+
88
+ 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' )
93
+
94
+ if var_name is None :
95
+ return False
96
+
97
+ 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 ('.' )
106
+ if len (var_pieces ) == 2 and check_var == var_name :
107
+ if value != old_value :
108
+ return True
109
+ 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 :
113
+ return True
114
+
115
+ return False
116
+
117
+
118
+
51
119
class TrigTime :
52
120
"""Class for trigger time functions."""
53
121
@@ -254,13 +322,18 @@ async def wait_until(
254
322
new_vars , func_args = None , {}
255
323
256
324
state_trig_ok = False
257
- if func_args .get ("var_name" , "" ) in state_trig_ident_any :
258
- state_trig_ok = True
259
- elif state_trig_eval :
260
- state_trig_ok = await state_trig_eval .eval (new_vars )
261
- exc = state_trig_eval .get_exception_obj ()
262
- if exc is not None :
263
- break
325
+
326
+ if not ident_any_values_changed (func_args , state_trig_ident_any ):
327
+ # if var_name not in func_args we are state_check_now
328
+ if "var_name" in func_args and not ident_values_changed (func_args , state_trig ):
329
+ continue
330
+
331
+ if state_trig_eval :
332
+ state_trig_ok = await state_trig_eval .eval (new_vars )
333
+ exc = state_trig_eval .get_exception_obj ()
334
+ if exc is not None :
335
+ break
336
+
264
337
if state_hold is not None :
265
338
if state_trig_ok :
266
339
if not state_trig_waiting :
@@ -644,112 +717,6 @@ def start(self):
644
717
self .task = Function .create_task (self .trigger_watch ())
645
718
_LOGGER .debug ("trigger %s is active" , self .name )
646
719
647
- def ident_any_values_changed (self , func_args ):
648
- """Check for changes to state or attributes on ident any vars"""
649
- value = func_args .get ('value' )
650
- old_value = func_args .get ('old_value' )
651
- var_name = func_args .get ('var_name' )
652
-
653
- if var_name is None :
654
- _LOGGER .debug (
655
- "%s ident_any change not detected because no var_name" ,
656
- self .name ,
657
- )
658
- return False
659
-
660
- for check_var in self .state_trig_ident_any :
661
- if check_var == var_name and old_value != value :
662
- _LOGGER .debug (
663
- "%s ident_any change detected at state" ,
664
- self .name ,
665
- )
666
- return True
667
-
668
- if check_var .startswith (f"{ var_name } ." ):
669
- var_pieces = check_var .split ('.' )
670
- if len (var_pieces ) == 3 and f"{ var_pieces [0 ]} .{ var_pieces [1 ]} " == var_name :
671
- if var_pieces [2 ] == "*" :
672
- # catch all has been requested, check all attributes for change
673
- all_attributes = set ()
674
- if value is not None :
675
- all_attributes |= set (value .__dict__ .keys ())
676
- if old_value is not None :
677
- all_attributes |= set (old_value .__dict__ .keys ())
678
- all_attributes -= STATE_VIRTUAL_ATTRS
679
- for attribute in all_attributes :
680
- attrib_val = getattr (value , attribute , None )
681
- attrib_old_val = getattr (old_value , attribute , None )
682
- if attrib_old_val != attrib_val :
683
- _LOGGER .debug (
684
- "%s ident_any change detected in * at %s" ,
685
- self .name ,
686
- attribute ,
687
- )
688
- return True
689
- else :
690
- attrib_val = getattr (value , var_pieces [2 ], None )
691
- attrib_old_val = getattr (old_value , var_pieces [2 ], None )
692
- if attrib_old_val != attrib_val :
693
- _LOGGER .debug (
694
- "%s ident_any change detected at %s" ,
695
- self .name ,
696
- var_pieces [2 ],
697
- )
698
- return True
699
-
700
- _LOGGER .debug (
701
- "%s no ident_any change detected" ,
702
- self .name ,
703
- )
704
- return False
705
-
706
- def ident_values_changed (self , func_args ):
707
- """Check for changes to state or attributes on ident vars"""
708
- value = func_args .get ('value' )
709
- old_value = func_args .get ('old_value' )
710
- var_name = func_args .get ('var_name' )
711
-
712
- if var_name is None :
713
- _LOGGER .debug (
714
- "%s ident changes not detected because no var_name" ,
715
- self .name ,
716
- )
717
- return False
718
-
719
- for check_var in self .state_trig_ident :
720
- if check_var in self .state_trig_ident_any :
721
- _LOGGER .debug (
722
- "%s ident change skipping %s because also ident_any" ,
723
- self .name ,
724
- check_var ,
725
- )
726
- continue
727
- var_pieces = check_var .split ('.' )
728
- if len (var_pieces ) == 2 and check_var == var_name :
729
- if value != old_value :
730
- _LOGGER .debug (
731
- "%s ident change detected at state" ,
732
- self .name
733
- )
734
- return True
735
- elif len (var_pieces ) == 3 and f"{ var_pieces [0 ]} .{ var_pieces [1 ]} " == var_name :
736
- attrib_val = getattr (value , var_pieces [2 ], None )
737
- attrib_old_val = getattr (old_value , var_pieces [2 ], None )
738
- if attrib_old_val != attrib_val :
739
- _LOGGER .debug (
740
- "%s ident change detected at attribute %s" ,
741
- self .name ,
742
- var_pieces [2 ]
743
- )
744
- return True
745
-
746
- _LOGGER .debug (
747
- "%s no ident change detected" ,
748
- self .name ,
749
- )
750
-
751
- return False
752
-
753
720
async def trigger_watch (self ):
754
721
"""Task that runs for each trigger, waiting for the next trigger and calling the function."""
755
722
@@ -845,9 +812,9 @@ async def trigger_watch(self):
845
812
elif notify_type == "state" :
846
813
new_vars , func_args = notify_info
847
814
848
- if not self . ident_any_values_changed (func_args ):
815
+ if not ident_any_values_changed (func_args , self . state_trig_ident_any ):
849
816
# if var_name not in func_args we are state_check_now
850
- if "var_name" in func_args and not self . ident_values_changed (func_args ):
817
+ if "var_name" in func_args and not ident_values_changed (func_args , self . state_trig_ident ):
851
818
continue
852
819
853
820
if self .state_trig_eval :
0 commit comments