Files @ 7b33cc2da5f0
Branch filter:

Location: HydroBot/hydrobot-software/alerts.py - annotation

matthewreed
Added new gas sensing and other stuff from a long time ago
c0dec1e0808c
c0dec1e0808c
d1c603090b0c
c0dec1e0808c
c0dec1e0808c
c0dec1e0808c
c0dec1e0808c
c0dec1e0808c
7b33cc2da5f0
c0dec1e0808c
7b33cc2da5f0
c0dec1e0808c
c0dec1e0808c
c0dec1e0808c
c0dec1e0808c
c0dec1e0808c
195dbcc38137
195dbcc38137
d1c603090b0c
195dbcc38137
195dbcc38137
195dbcc38137
d1c603090b0c
d1c603090b0c
d1c603090b0c
195dbcc38137
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
195dbcc38137
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
195dbcc38137
c0dec1e0808c
c0dec1e0808c
c0dec1e0808c
c0dec1e0808c
c0dec1e0808c
c0dec1e0808c
c0dec1e0808c
c0dec1e0808c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
7b33cc2da5f0
d1c603090b0c
d1c603090b0c
d1c603090b0c
195dbcc38137
195dbcc38137
195dbcc38137
195dbcc38137
195dbcc38137
195dbcc38137
195dbcc38137
d1c603090b0c
d1c603090b0c
195dbcc38137
195dbcc38137
195dbcc38137
195dbcc38137
195dbcc38137
195dbcc38137
195dbcc38137
195dbcc38137
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
195dbcc38137
195dbcc38137
d1c603090b0c
d1c603090b0c
7b33cc2da5f0
7b33cc2da5f0
d1c603090b0c
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
d1c603090b0c
195dbcc38137
195dbcc38137
195dbcc38137
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
d1c603090b0c
195dbcc38137
195dbcc38137
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
7b33cc2da5f0
195dbcc38137
import smtplib
from email.mime.text import MIMEText
from abc import ABCMeta, abstractmethod
import configparser
import logging

class AlertManager:

    def __init__(self, database, config):
        self.logger = logging.getLogger('hydrobot')
        self.database = database
        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.info("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 = self.manager.database.read_value(self.output_module, self.output_type, int(self.output_number))
        print("Output status: " + str(output_status))
        #get input status
        input_status = self.manager.database.read_value(self.input_module, self.input_type, int(self.input_number))
        print("Input status: " + str(input_status))
        
        if input_status != None:
        
            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 measurement
        measurement = self.manager.database.read_value(self.input_module, self.input_type, int(self.input_number))
        print("Measurement: " + str(measurement))
        
        if measurement != None:
            if measurement > self.high_threshold:
                #alert!
                #print("Alert! " + self.name + " is too high!")
                self.manager.send_alert("Alert! " + self.name + " is too high!")
            if measurement < self.low_threshold:
                #alert!
                #print("Alert! " + self.name + " is too low!")
                self.manager.send_alert("Alert! " + self.name + " is too low!")