diff --git a/src/core/control.py b/src/core/control.py index 7cba546dfa640e453488fa681d646024e02d7491..3d28993c3157eb08b990aedab18a86e1d0dcf70a 100644 --- a/src/core/control.py +++ b/src/core/control.py @@ -186,7 +186,8 @@ class EngineExecutor(Timer): Primarily used for automations performed by the scheduler. """ logger = logging.getLogger("AuraEngine") - timer_store = {} + timer_store = {} + parent_timer = None child_timer = None direct_exec = None timer_id = None @@ -196,20 +197,22 @@ class EngineExecutor(Timer): dt = None - def __init__(self, timer_type="BASE", child_timer=None, due_time=None, func=None, param=None): + def __init__(self, timer_type="BASE", parent_timer=None, due_time=None, func=None, param=None): """ Constructor Args: timer_type (String): Prefix used for the `timer_id` to make it unique - child_timer (EngineExeuctor): Child action which is bound to this timer + parent_timer (EngineExeuctor): Parent action which is a prerequisite for this timer due_time (Float): When timer should be executed. For values <= 0 execution happens immediately in a threaded way func (function): The function to be called param (object): Parameter passt to the function """ from src.core.engine import Engine now_unix = Engine.engine_time() - self.child_timer = child_timer + self.parent_timer = parent_timer + if self.parent_timer: + self.parent_timer.child_timer = self self.direct_exec = False self.timer_type = timer_type self.timer_id = f"{timer_type}:{func.__name__}:{due_time}" @@ -230,30 +233,40 @@ class EngineExecutor(Timer): self.exec_now() elif diff == 0: self.logger.info(f"Timer '{self.timer_id}' to be executed immediately") - self.exec_now() - else: + self.exec_now() + else: self.exec_timed() self.start() self.update_store() + def wait_for_parent(self): + """ + Child timers are dependend on their parents. So let's wait until parents are done with their stuff. + """ + if self.parent_timer and self.parent_timer.is_alive(): + while(self.parent_timer.is_alive()): + self.logger.info(f"Timer '{self.timer_id}' is waiting for parent timer '{self.parent_timer.timer_id}' to finish") + time.sleep(0.2) + def exec_now(self): """ Immediate execution within a thread. It's not stored in the timer store. """ self.direct_exec = True + self.wait_for_parent() thread = Thread(target = self.func, args = (self.param,)) thread.start() - def exec_timed(self): """ Timed execution in a thread. """ def wrapper_func(param=None): + self.wait_for_parent() # Remove from store self.logger.info(SU.green(f"Removing old timer with ID: {self.timer_id}")) @@ -311,7 +324,8 @@ class EngineExecutor(Timer): msg += "None available!\n" else: for timer in timers: - msg += f" => {str(timer)}\n" + if not timer.parent_timer: + msg += f" => {str(timer)}\n" if timer.child_timer: msg += f" => {str(timer.child_timer)}\n"