2121from .function import Function
2222from .mqtt import Mqtt
2323from .state import STATE_VIRTUAL_ATTRS , State
24+ from .webhook import Webhook
2425
2526_LOGGER = logging .getLogger (LOGGER_PATH + ".trigger" )
2627
@@ -222,13 +223,22 @@ async def wait_until(
222223 time_trigger = None ,
223224 event_trigger = None ,
224225 mqtt_trigger = None ,
226+ webhook_trigger = None ,
227+ webhook_local_only = True ,
228+ webhook_methods = None ,
225229 timeout = None ,
226230 state_hold = None ,
227231 state_hold_false = None ,
228232 __test_handshake__ = None ,
229233 ):
230234 """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 :
235+ if (
236+ state_trigger is None
237+ and time_trigger is None
238+ and event_trigger is None
239+ and mqtt_trigger is None
240+ and webhook_trigger is None
241+ ):
232242 if timeout is not None :
233243 await asyncio .sleep (timeout )
234244 return {"trigger_type" : "timeout" }
@@ -238,6 +248,7 @@ async def wait_until(
238248 state_trig_eval = None
239249 event_trig_expr = None
240250 mqtt_trig_expr = None
251+ webhook_trig_expr = None
241252 exc = None
242253 notify_q = asyncio .Queue (0 )
243254
@@ -349,6 +360,26 @@ async def wait_until(
349360 State .notify_del (state_trig_ident , notify_q )
350361 raise exc
351362 await Mqtt .notify_add (mqtt_trigger [0 ], notify_q )
363+ if webhook_trigger is not None :
364+ if isinstance (webhook_trigger , str ):
365+ webhook_trigger = [webhook_trigger ]
366+ if len (webhook_trigger ) > 1 :
367+ webhook_trig_expr = AstEval (
368+ f"{ ast_ctx .name } webhook_trigger" ,
369+ ast_ctx .get_global_ctx (),
370+ logger_name = ast_ctx .get_logger_name (),
371+ )
372+ Function .install_ast_funcs (webhook_trig_expr )
373+ webhook_trig_expr .parse (webhook_trigger [1 ], mode = "eval" )
374+ exc = webhook_trig_expr .get_exception_obj ()
375+ if exc is not None :
376+ if len (state_trig_ident ) > 0 :
377+ State .notify_del (state_trig_ident , notify_q )
378+ raise exc
379+ if webhook_methods is None :
380+ webhook_methods = {"POST" , "PUT" }
381+ Webhook .notify_add (webhook_trigger [0 ], webhook_local_only , webhook_methods , notify_q )
382+
352383 time0 = time .monotonic ()
353384
354385 if __test_handshake__ :
@@ -394,7 +425,12 @@ async def wait_until(
394425 state_trig_timeout = True
395426 time_next = now + dt .timedelta (seconds = this_timeout )
396427 if this_timeout is None :
397- if state_trigger is None and event_trigger is None and mqtt_trigger is None :
428+ if (
429+ state_trigger is None
430+ and event_trigger is None
431+ and mqtt_trigger is None
432+ and webhook_trigger is None
433+ ):
398434 _LOGGER .debug (
399435 "trigger %s wait_until no next time - returning with none" ,
400436 ast_ctx .name ,
@@ -527,6 +563,17 @@ async def wait_until(
527563 if mqtt_trig_ok :
528564 ret = notify_info
529565 break
566+ elif notify_type == "webhook" :
567+ if webhook_trig_expr is None :
568+ ret = notify_info
569+ break
570+ webhook_trig_ok = await webhook_trig_expr .eval (notify_info )
571+ exc = webhook_trig_expr .get_exception_obj ()
572+ if exc is not None :
573+ break
574+ if webhook_trig_ok :
575+ ret = notify_info
576+ break
530577 else :
531578 _LOGGER .error (
532579 "trigger %s wait_until got unexpected queue message %s" ,
@@ -540,6 +587,8 @@ async def wait_until(
540587 Event .notify_del (event_trigger [0 ], notify_q )
541588 if mqtt_trigger is not None :
542589 Mqtt .notify_del (mqtt_trigger [0 ], notify_q )
590+ if webhook_trigger is not None :
591+ Webhook .notify_del (webhook_trigger [0 ], notify_q )
543592 if exc :
544593 raise exc
545594 return ret
@@ -826,6 +875,10 @@ def __init__(
826875 self .event_trigger_kwargs = trig_cfg .get ("event_trigger" , {}).get ("kwargs" , {})
827876 self .mqtt_trigger = trig_cfg .get ("mqtt_trigger" , {}).get ("args" , None )
828877 self .mqtt_trigger_kwargs = trig_cfg .get ("mqtt_trigger" , {}).get ("kwargs" , {})
878+ self .webhook_trigger = trig_cfg .get ("webhook_trigger" , {}).get ("args" , None )
879+ self .webhook_trigger_kwargs = trig_cfg .get ("webhook_trigger" , {}).get ("kwargs" , {})
880+ self .webhook_local_only = self .webhook_trigger_kwargs .get ("local_only" , True )
881+ self .webhook_methods = self .webhook_trigger_kwargs .get ("methods" , {"POST" , "PUT" })
829882 self .state_active = trig_cfg .get ("state_active" , {}).get ("args" , None )
830883 self .time_active = trig_cfg .get ("time_active" , {}).get ("args" , None )
831884 self .time_active_hold_off = trig_cfg .get ("time_active" , {}).get ("kwargs" , {}).get ("hold_off" , None )
@@ -842,6 +895,7 @@ def __init__(
842895 self .state_trig_ident_any = set ()
843896 self .event_trig_expr = None
844897 self .mqtt_trig_expr = None
898+ self .webhook_trig_expr = None
845899 self .have_trigger = False
846900 self .setup_ok = False
847901 self .run_on_startup = False
@@ -933,6 +987,21 @@ def __init__(
933987 return
934988 self .have_trigger = True
935989
990+ if self .webhook_trigger is not None :
991+ if len (self .webhook_trigger ) == 2 :
992+ self .webhook_trig_expr = AstEval (
993+ f"{ self .name } @webhook_trigger()" ,
994+ self .global_ctx ,
995+ logger_name = self .name ,
996+ )
997+ Function .install_ast_funcs (self .webhook_trig_expr )
998+ self .webhook_trig_expr .parse (self .webhook_trigger [1 ], mode = "eval" )
999+ exc = self .webhook_trig_expr .get_exception_long ()
1000+ if exc is not None :
1001+ self .webhook_trig_expr .get_logger ().error (exc )
1002+ return
1003+ self .have_trigger = True
1004+
9361005 self .setup_ok = True
9371006
9381007 def stop (self ):
@@ -945,6 +1014,8 @@ def stop(self):
9451014 Event .notify_del (self .event_trigger [0 ], self .notify_q )
9461015 if self .mqtt_trigger is not None :
9471016 Mqtt .notify_del (self .mqtt_trigger [0 ], self .notify_q )
1017+ if self .webhook_trigger is not None :
1018+ Webhook .notify_del (self .webhook_trigger [0 ], self .notify_q )
9481019 if self .task :
9491020 Function .reaper_cancel (self .task )
9501021 self .task = None
@@ -995,6 +1066,11 @@ async def trigger_watch(self):
9951066 if self .mqtt_trigger is not None :
9961067 _LOGGER .debug ("trigger %s adding mqtt_trigger %s" , self .name , self .mqtt_trigger [0 ])
9971068 await Mqtt .notify_add (self .mqtt_trigger [0 ], self .notify_q )
1069+ if self .webhook_trigger is not None :
1070+ _LOGGER .debug ("trigger %s adding webhook_trigger %s" , self .name , self .webhook_trigger [0 ])
1071+ Webhook .notify_add (
1072+ self .webhook_trigger [0 ], self .webhook_local_only , self .webhook_methods , self .notify_q
1073+ )
9981074
9991075 last_trig_time = None
10001076 last_state_trig_time = None
@@ -1182,6 +1258,11 @@ async def trigger_watch(self):
11821258 user_kwargs = self .mqtt_trigger_kwargs .get ("kwargs" , {})
11831259 if self .mqtt_trig_expr :
11841260 trig_ok = await self .mqtt_trig_expr .eval (notify_info )
1261+ elif notify_type == "webhook" :
1262+ func_args = notify_info
1263+ user_kwargs = self .webhook_trigger_kwargs .get ("kwargs" , {})
1264+ if self .webhook_trig_expr :
1265+ trig_ok = await self .webhook_trig_expr .eval (notify_info )
11851266
11861267 else :
11871268 user_kwargs = self .time_trigger_kwargs .get ("kwargs" , {})
@@ -1237,6 +1318,8 @@ async def trigger_watch(self):
12371318 Event .notify_del (self .event_trigger [0 ], self .notify_q )
12381319 if self .mqtt_trigger is not None :
12391320 Mqtt .notify_del (self .mqtt_trigger [0 ], self .notify_q )
1321+ if self .webhook_trigger is not None :
1322+ Webhook .notify_del (self .webhook_trigger [0 ], self .notify_q )
12401323 return
12411324
12421325 def call_action (self , notify_type , func_args , run_task = True ):
0 commit comments