21
21
from .function import Function
22
22
from .mqtt import Mqtt
23
23
from .state import STATE_VIRTUAL_ATTRS , State
24
+ from .webhook import Webhook
24
25
25
26
_LOGGER = logging .getLogger (LOGGER_PATH + ".trigger" )
26
27
@@ -222,13 +223,14 @@ async def wait_until(
222
223
time_trigger = None ,
223
224
event_trigger = None ,
224
225
mqtt_trigger = None ,
226
+ webhook_trigger = None ,
225
227
timeout = None ,
226
228
state_hold = None ,
227
229
state_hold_false = None ,
228
230
__test_handshake__ = None ,
229
231
):
230
232
"""Wait for zero or more triggers, until an optional timeout."""
231
- if state_trigger is None and time_trigger is None and event_trigger is None and mqtt_trigger is None :
233
+ if state_trigger is None and time_trigger is None and event_trigger is None and mqtt_trigger is None and webhook_trigger is None :
232
234
if timeout is not None :
233
235
await asyncio .sleep (timeout )
234
236
return {"trigger_type" : "timeout" }
@@ -238,6 +240,7 @@ async def wait_until(
238
240
state_trig_eval = None
239
241
event_trig_expr = None
240
242
mqtt_trig_expr = None
243
+ webhook_trig_expr = None
241
244
exc = None
242
245
notify_q = asyncio .Queue (0 )
243
246
@@ -349,6 +352,22 @@ async def wait_until(
349
352
State .notify_del (state_trig_ident , notify_q )
350
353
raise exc
351
354
await Mqtt .notify_add (mqtt_trigger [0 ], notify_q )
355
+ if webhook_trigger is not None :
356
+ if isinstance (webhook_trigger , str ):
357
+ webhook_trigger = [webhook_trigger ]
358
+ if len (webhook_trigger ) > 1 :
359
+ webhook_trig_expr = AstEval (
360
+ f"{ ast_ctx .name } webhook_trigger" ,
361
+ ast_ctx .get_global_ctx (),
362
+ logger_name = ast_ctx .get_logger_name (),
363
+ )
364
+ Function .install_ast_funcs (webhook_trig_expr )
365
+ webhook_trig_expr .parse (webhook_trigger [1 ], mode = "eval" )
366
+ exc = webhook_trig_expr .get_exception_obj ()
367
+ if exc is not None :
368
+ if len (state_trig_ident ) > 0 :
369
+ State .notify_del (state_trig_ident , notify_q )
370
+ raise exc
352
371
time0 = time .monotonic ()
353
372
354
373
if __test_handshake__ :
@@ -394,7 +413,7 @@ async def wait_until(
394
413
state_trig_timeout = True
395
414
time_next = now + dt .timedelta (seconds = this_timeout )
396
415
if this_timeout is None :
397
- if state_trigger is None and event_trigger is None and mqtt_trigger is None :
416
+ if state_trigger is None and event_trigger is None and mqtt_trigger is None and webhook_trigger is None :
398
417
_LOGGER .debug (
399
418
"trigger %s wait_until no next time - returning with none" ,
400
419
ast_ctx .name ,
@@ -527,6 +546,17 @@ async def wait_until(
527
546
if mqtt_trig_ok :
528
547
ret = notify_info
529
548
break
549
+ elif notify_type == "webhook" :
550
+ if webhook_trig_expr is None :
551
+ ret = notify_info
552
+ break
553
+ webhook_trig_ok = await webhook_trig_expr .eval (notify_info )
554
+ exc = webhook_trig_expr .get_exception_obj ()
555
+ if exc is not None :
556
+ break
557
+ if webhook_trig_ok :
558
+ ret = notify_info
559
+ break
530
560
else :
531
561
_LOGGER .error (
532
562
"trigger %s wait_until got unexpected queue message %s" ,
@@ -540,6 +570,8 @@ async def wait_until(
540
570
Event .notify_del (event_trigger [0 ], notify_q )
541
571
if mqtt_trigger is not None :
542
572
Mqtt .notify_del (mqtt_trigger [0 ], notify_q )
573
+ if webhook_trigger is not None :
574
+ Webhook .notify_del (webhook_trigger [0 ], notify_q )
543
575
if exc :
544
576
raise exc
545
577
return ret
@@ -826,6 +858,8 @@ def __init__(
826
858
self .event_trigger_kwargs = trig_cfg .get ("event_trigger" , {}).get ("kwargs" , {})
827
859
self .mqtt_trigger = trig_cfg .get ("mqtt_trigger" , {}).get ("args" , None )
828
860
self .mqtt_trigger_kwargs = trig_cfg .get ("mqtt_trigger" , {}).get ("kwargs" , {})
861
+ self .webhook_trigger = trig_cfg .get ("webhook_trigger" , {}).get ("args" , None )
862
+ self .webhook_trigger_kwargs = trig_cfg .get ("webhook_trigger" , {}).get ("kwargs" , {})
829
863
self .state_active = trig_cfg .get ("state_active" , {}).get ("args" , None )
830
864
self .time_active = trig_cfg .get ("time_active" , {}).get ("args" , None )
831
865
self .time_active_hold_off = trig_cfg .get ("time_active" , {}).get ("kwargs" , {}).get ("hold_off" , None )
@@ -842,6 +876,7 @@ def __init__(
842
876
self .state_trig_ident_any = set ()
843
877
self .event_trig_expr = None
844
878
self .mqtt_trig_expr = None
879
+ self .webhook_trig_expr = None
845
880
self .have_trigger = False
846
881
self .setup_ok = False
847
882
self .run_on_startup = False
@@ -933,6 +968,21 @@ def __init__(
933
968
return
934
969
self .have_trigger = True
935
970
971
+ if self .webhook_trigger is not None :
972
+ if len (self .webhook_trigger ) == 2 :
973
+ self .webhook_trig_expr = AstEval (
974
+ f"{ self .name } @webhook_trigger()" ,
975
+ self .global_ctx ,
976
+ logger_name = self .name ,
977
+ )
978
+ Function .install_ast_funcs (self .webhook_trig_expr )
979
+ self .webhook_trig_expr .parse (self .webhook_trigger [1 ], mode = "eval" )
980
+ exc = self .webhook_trig_expr .get_exception_long ()
981
+ if exc is not None :
982
+ self .webhook_trig_expr .get_logger ().error (exc )
983
+ return
984
+ self .have_trigger = True
985
+
936
986
self .setup_ok = True
937
987
938
988
def stop (self ):
@@ -945,6 +995,8 @@ def stop(self):
945
995
Event .notify_del (self .event_trigger [0 ], self .notify_q )
946
996
if self .mqtt_trigger is not None :
947
997
Mqtt .notify_del (self .mqtt_trigger [0 ], self .notify_q )
998
+ if self .webhook_trigger is not None :
999
+ Webhook .notify_del (self .webhook_trigger [0 ], self .notify_q )
948
1000
if self .task :
949
1001
Function .reaper_cancel (self .task )
950
1002
self .task = None
@@ -995,6 +1047,9 @@ async def trigger_watch(self):
995
1047
if self .mqtt_trigger is not None :
996
1048
_LOGGER .debug ("trigger %s adding mqtt_trigger %s" , self .name , self .mqtt_trigger [0 ])
997
1049
await Mqtt .notify_add (self .mqtt_trigger [0 ], self .notify_q )
1050
+ if self .webhook_trigger is not None :
1051
+ _LOGGER .debug ("trigger %s adding webhook_trigger %s" , self .name , self .webhook_trigger [0 ])
1052
+ Webhook .notify_add (self .webhook_trigger [0 ], self .notify_q )
998
1053
999
1054
last_trig_time = None
1000
1055
last_state_trig_time = None
@@ -1237,6 +1292,8 @@ async def trigger_watch(self):
1237
1292
Event .notify_del (self .event_trigger [0 ], self .notify_q )
1238
1293
if self .mqtt_trigger is not None :
1239
1294
Mqtt .notify_del (self .mqtt_trigger [0 ], self .notify_q )
1295
+ if self .webhook_trigger is not None :
1296
+ Webhook .notify_del (self .webhook_trigger [0 ], self .notify_q )
1240
1297
return
1241
1298
1242
1299
def call_action (self , notify_type , func_args , run_task = True ):
0 commit comments