feat: add debounce_seconds parameter to EventDispatcher for event trigger management
This commit is contained in:
@@ -42,6 +42,9 @@ import json
|
||||
# <field>: <value>
|
||||
# reset_data: # optional — latch reset filter
|
||||
# <field>: <value>
|
||||
# debounce_seconds: <float> # optional — ignore re-triggers within
|
||||
# # this delay (seconds). Useful for
|
||||
# # buttons that fire duplicate events.
|
||||
#
|
||||
# Usage:
|
||||
# handler = EventHandler(ad_api, self.args['events_to_listen'], my_callback)
|
||||
@@ -57,7 +60,7 @@ import json
|
||||
# =============================================================================
|
||||
|
||||
class EventDispatcher:
|
||||
def __init__(self,ad_api,event_name,callback,event_data,reset_data,event_context):
|
||||
def __init__(self,ad_api,event_name,callback,event_data,reset_data,event_context,debounce_seconds=None):
|
||||
self.ad_api = ad_api
|
||||
event_data = self._resolve_zha_device_name(event_data)
|
||||
reset_data = self._resolve_zha_device_name(reset_data)
|
||||
@@ -67,6 +70,8 @@ class EventDispatcher:
|
||||
self.reset_data = reset_data
|
||||
self.waiting_for_reset = False
|
||||
self.event_context = event_context
|
||||
self.debounce_seconds = debounce_seconds
|
||||
self._last_trigger_time = None
|
||||
if event_data == None:
|
||||
self.ad_api.listen_event(self.on_event,event_name)
|
||||
else:
|
||||
@@ -159,6 +164,13 @@ class EventDispatcher:
|
||||
|
||||
#special threatment for event
|
||||
if match_event_data and not self.waiting_for_reset:
|
||||
if self.debounce_seconds is not None:
|
||||
import time
|
||||
now = time.monotonic()
|
||||
if self._last_trigger_time is not None and (now - self._last_trigger_time) < self.debounce_seconds:
|
||||
return False
|
||||
self._last_trigger_time = now
|
||||
|
||||
if self.reset_data != None:
|
||||
self.waiting_for_reset = True
|
||||
|
||||
@@ -173,7 +185,7 @@ class EventDispatcher:
|
||||
class EventHandler:
|
||||
def __init__(self, ad_api,events_block,callback,event_context = None): #event_context is passed back to the CB has a context
|
||||
def register_event_with_params(event_block,callback,event_context):
|
||||
self.add_dispatcher(event_block['event_name'],callback,event_block['event_data'] if 'event_data' in event_block else None, event_block['reset_data'] if 'reset_data' in event_block else None,event_context)
|
||||
self.add_dispatcher(event_block['event_name'],callback,event_block['event_data'] if 'event_data' in event_block else None, event_block['reset_data'] if 'reset_data' in event_block else None,event_context, event_block.get('debounce_seconds'))
|
||||
|
||||
self.__ad_api = ad_api
|
||||
self.event_dispatchers = []
|
||||
@@ -185,7 +197,7 @@ class EventHandler:
|
||||
for event_block in events_block.values():
|
||||
register_event_with_params(event_block,callback,event_context)
|
||||
|
||||
def add_dispatcher(self,event_name,callback,event_data = None,reset_data = None ,event_context = None):
|
||||
def add_dispatcher(self,event_name,callback,event_data = None,reset_data = None ,event_context = None, debounce_seconds = None):
|
||||
self.__ad_api.log_info(f'Registering dispatcher {callback.__name__} for event "{event_name}" ({event_data})')
|
||||
dispatcher = EventDispatcher(self.__ad_api,event_name,callback,event_data,reset_data,event_context)
|
||||
dispatcher = EventDispatcher(self.__ad_api,event_name,callback,event_data,reset_data,event_context,debounce_seconds)
|
||||
self.event_dispatchers.append(dispatcher)
|
||||
Reference in New Issue
Block a user