import numpy as np import time from utils import send_update from humidifier import Humidifier, HumidifierV2 from humidifier_v3 import HumidifierV3 class Controller: def __init__(self, humidifiers): self.target_lower = 83 self.target_upper = 87 self.feedforward_coeff = 50 self.last_toggle = 0 self._manual_mode = False self.manual_on = False self.manual_timeout = 0 self.manual_duration = 40 self.humidifier_history = np.zeros(50) self.first_sample = False self.humidifiers = humidifiers @property def manual_mode(self): return self._manual_mode @manual_mode.setter def manual_mode(self, on): self._manual_mode = on send_update({"status": {"manual_mode": on}}) def set_checked(self, s, humidifier, on): if time.time() - self.last_toggle > 0.8: print("setting {} to {}".format(humidifier, on)) if isinstance(humidifier, HumidifierV3): humidifier.set(s, on) elif isinstance(humidifier, Humidifier) or isinstance(humidifier, HumidifierV2): humidifier.toggle(s) self.last_toggle = time.time() def update(self, s, humidity): if self.first_sample: self.humidifier_history[:] = humidity self.first_sample = False else: self.humidifier_history[:-1] = self.humidifier_history[1:] self.humidifier_history[-1] = humidity # compensate for the slow response time by adding a little feed forward # using the slope of the humidifier data slope = (self.humidifier_history[-1] - self.humidifier_history[0])/self.humidifier_history.shape[0] comp_humidity = humidity + self.feedforward_coeff*slope if self.manual_mode and time.time() > self.manual_timeout: self.manual_mode = False if self.manual_mode: for humidifier in self.humidifiers: if not humidifier.on and self.manual_on: self.set_checked(s, humidifier, True) elif not humidifier.off and not self.manual_on: self.set_checked(s, humidifier, False) else: if comp_humidity < self.target_lower: for humidifier in self.humidifiers: if not humidifier.on: self.set_checked(s, humidifier, True) elif comp_humidity > self.target_upper: for humidifier in self.humidifiers: if not humidifier.off: self.set_checked(s, humidifier, False)