import abc from components.connectable import Connectable from contextlib import contextmanager class AStirrer(Connectable): def __init__(self, dt, simulated=True): Connectable.__init__(self, simulated) self.dt = dt self.speed = 0 self.cycleTime = 1 self.dutyCycle = 1 self.cycleCounter = 0 self.isOn = 1 def process(self): isOn = self.isOn self.cycleCounter += self.dt if self.cycleCounter >= self.cycleTime: self.cycleCounter -= self.cycleTime isOn = 0 if self.cycleCounter >= (self.cycleTime * (1-self.dutyCycle)): if not isOn: isOn = 1 if self.isOn != isOn: if isOn: self._on_set_speed(self.speed) else: self._on_set_speed(0) self.isOn = isOn self._on_process() def set_speed(self, speed): self.speed = speed if self.isOn or self.dutyCycle == 1: self._on_set_speed(speed) def set_cycle_time(self, time): self.cycleTime = time def set_duty_cycle(self, dutyCycle): self.dutyCycle = dutyCycle @abc.abstractmethod def get_speed(self): return None @abc.abstractmethod def _on_set_speed(self, speed): pass @abc.abstractmethod def _on_process(self): pass @contextmanager def open(self): try: self.activate(True) yield None finally: self.activate(False) return None @abc.abstractmethod def activate(self, enable): pass @abc.abstractmethod def is_activated(self): pass