import smtplib from email.mime.text import MIMEText from abc import ABCMeta, abstractmethod import configparser import logging class AlertManager: def __init__(self, config): self.logger = logging.getLogger('hydrobot') self.from_addr = config.get("alerts", "from_address") self.to_addr = config.get("alerts", "to_address") self.mail_server = config.get("alerts", "mail_server") self.username = config.get("alerts", "username") self.password = config.get("alerts", "password") self.alerts = [] self.load_alerts(config) def load_alerts(self, config): for section in config.sections(): if "alert" in section and section != "alerts": type = config.get(section, "type") if type == "output_feedback": name = config.get(section, "name") output_module = config.get(section, "output_module") output_type = config.get(section, "output_type") output_number = config.get(section, "output_number") input_module = config.get(section, "input_module") input_type = config.get(section, "input_type") input_number = config.get(section, "input_number") on_threshold = config.getfloat(section, "on_threshold") off_threshold = config.getfloat(section, "off_threshold") hysteresis = config.getfloat(section, "hysteresis") self.alerts.append(OutputFeedbackAlert(self, name, output_module, output_type, output_number, input_module, input_type, input_number, on_threshold, off_threshold, hysteresis)) elif type == "measurement": name = config.get(section, "name") input_module = config.get(section, "input_module") input_type = config.get(section, "input_type") input_number = config.get(section, "input_number") high_threshold = config.getfloat(section, "high_threshold") low_threshold = config.getfloat(section, "low_threshold") hysteresis = config.getfloat(section, "hysteresis") self.alerts.append(MeasurementAlert(self, name, input_module, input_type, input_number, high_threshold, low_threshold, hysteresis)) def send_alert(self, message): msg = MIMEText(message) msg['Subject'] = "HydroBot Alert" msg['From'] = self.from_addr msg['To'] = self.to_addr try: server = smtplib.SMTP(self.mail_server) server.ehlo() server.starttls() server.login(self.username, self.password) server.send_message(msg) server.quit() self.logger.debug("Sent email alert: " + message) except: self.logger.error("Sending email alert failed!") def evaluate_alerts(self): for alert in self.alerts: alert.evalutate() class Alert(metaclass=ABCMeta): def __init__(self, manager, name): self.manager = manager self.name = name @abstractmethod def evalutate(self): pass class OutputFeedbackAlert(Alert): def __init__(self, manager, name, output_module, output_type, output_number, input_module, input_type, input_number, on_threshold, off_threshold, hysteresis): super(OutputFeedbackAlert, self).__init__(manager, name) self.output_module = output_module self.output_type = output_type self.output_number = output_number self.input_module = input_module self.input_type = input_type self.input_number = input_number self.on_threshold = on_threshold self.off_threshold = off_threshold self.hysteresis = hysteresis def evalutate(self): #get output status output_status = 1 #get input status input_status = 0 if output_status == 1: if input_status < self.on_threshold: #alert! print("Alert! " + self.name + " did not turn on!") self.manager.send_alert("Alert! " + self.name + " did not turn on!") if output_status == 0: if input_status > self.off_threshold: #alert! print("Alert! " + self.name + " did not turn off!") self.manager.send_alert("Alert! " + self.name + " did not turn off!") class MeasurementAlert(Alert): def __init__(self, manager, name, input_module, input_type, input_number, high_threshold, low_threshold, hysteresis): super(MeasurementAlert, self).__init__(manager, name) self.input_module = input_module self.input_type = input_type self.input_number = input_number self.high_threshold = high_threshold self.low_threshold = low_threshold self.hysteresis = hysteresis def evalutate(self): #get input status input_status = 0 if input_status > self.high_threshold: #alert! print("Alert! " + self.name + " is too high!") self.manager.send_alert("Alert! " + self.name + " is too high!") if input_status < self.low_threshold: #alert! print("Alert! " + self.name + " is too low!") self.manager.send_alert("Alert! " + self.name + " is too low!")