Changeset - d1c603090b0c
[Not reviewed]
refactor
0 2 0
matthewreed - 8 years ago 2017-09-24 22:29:12

Added alert evalutation
2 files changed with 113 insertions and 52 deletions:
0 comments (0 inline, 0 general)
alerts.py
Show inline comments
 
import smtplib
 
from email.mime.text import MIMEText
 
from abc import ABCMeta, abstractmethod
 
import configparser
 
import logging
 
 
@@ -14,31 +15,34 @@ class AlertManager:
 
        self.password = config.get("alerts", "password")
 
        
 
        self.alerts = []
 
        load_alerts(config)
 
        self.load_alerts(config)
 
        
 
    def load_alerts(self, config):
 
        
 
        for section in self.config.sections():
 
            if "alert" in section:
 
                type = self.config.get(section, "type")
 
        for section in config.sections():
 
            if "alert" in section and section != "alerts":
 
                type = config.get(section, "type")
 
                if type == "output_feedback":
 
                    name = self.config.get(section, "name")
 
                    output_module = self.config.get(section, "output_module")
 
                    output = self.config.get(section, "output")
 
                    input_module = self.config.get(section, "input_module")
 
                    input = self.config.get(section, "input")
 
                    on_threshold = self.config.get(section, "on_threshold")
 
                    off_threshold = self.config.get(section, "off_threshold")
 
                    deadband = self.config.get(section, "deadband")
 
                    self.alerts.append(OutputFeedbackAlert(name, output_module, output, input_module, input, on_threshold, off_threshold, deadband))
 
                    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 = self.config.get(section, "name")
 
                    input_module = self.config.get(section, "input_module")
 
                    input = self.config.get(section, "input")
 
                    high_threshold = self.config.get(section, "high_threshold")
 
                    low_threshold = self.config.get(section, "low_threshold")
 
                    deadband = self.config.get(section, "deadband")
 
                    self.alerts.append(MeasurementAlert(name, input_module, input, high_threshold, low_threshold, deadband))
 
                    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):
 
@@ -48,12 +52,17 @@ class AlertManager:
 
        msg['From'] = self.from_addr
 
        msg['To'] = self.to_addr
 
        
 
        server = smtplib.SMTP(self.mail_server)
 
        server.ehlo()
 
        server.starttls()
 
        server.login(self.username, self.password)
 
        server.send_message(msg)
 
        server.quit()
 
        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:
 
@@ -61,7 +70,8 @@ class AlertManager:
 
 
class Alert(metaclass=ABCMeta):
 
    
 
    def __init__(self, name):
 
    def __init__(self, manager, name):
 
        self.manager = manager
 
        self.name = name
 
        
 
    @abstractmethod
 
@@ -70,17 +80,58 @@ class Alert(metaclass=ABCMeta):
 
        
 
class OutputFeedbackAlert(Alert):
 
    
 
    def __init__(self, name, output_module, output, input_module, input, on_threshold, off_threshold, deadband):
 
        super(Alert, self).__init__(name)
 
    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):
 
        print(self.name)
 
        
 
        #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, name, input_module, input, high_threshold, low_threshold, deadband):
 
        super(Alert, self).__init__(name)
 
    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):
 
        print(self.name)
 
        #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!")
 
hydrobot_example.conf
Show inline comments
 
@@ -29,67 +29,77 @@ off_duration: [0, 0, 0, 0, 10]
 
name: "Pump"
 
type: output_feedback
 
output_module: RelayDrive1
 
output: output_1
 
output_type: digital_output
 
output_number: 1
 
input_module: RelayDrive1
 
input: input_1
 
input_type: frequency_input
 
input_number: 1
 
on_threshold: 50
 
off_threshold: 1
 
deadband: 5
 
hysteresis: 5
 

	
 
[alert2]
 
name: "Light"
 
type: output_feedback
 
output_module: RelayDrive1
 
output: output_1
 
output_type: digital_output
 
output_number: 1
 
input_module: AirSense1
 
input: ambient_light
 
input_type: ambient_light
 
input_number: 0
 
on_threshold: 5000
 
off_threshold: 500
 
deadband: 10
 
hysteresis: 10
 

	
 
[alert3]
 
name: "Lamp Dim"
 
type: output_feedback
 
output_module: RelayDrive1
 
output: output_1
 
output_type: digital_output
 
output_number: 1
 
input_module: AirSense1
 
input: ambient_light
 
input_type: ambient_light
 
input_number: 0
 
on_threshold: 10000
 
off_threshold: None
 
deadband: 10
 
off_threshold: 0
 
hysteresis: 10
 

	
 
[alert4]
 
name: "Air Temperature"
 
type: measurement
 
input_module: AirSense1
 
input: air_temp
 
input_type: air_temp
 
input_number: 0
 
high_threshold: 35
 
low_threshold: 15
 
deadband: 10
 
hysteresis: 10
 

	
 
[alert5]
 
name: "Air Humidity"
 
type: measurement
 
input_module: AirSense1
 
input: air_humid
 
input_type: air_humid
 
input_number: 0
 
high_threshold: 80
 
low_threshold: 30
 
deadband: 10
 
hysteresis: 10
 

	
 
[alert6]
 
name: "Water Level"
 
type: measurement
 
input_module: WaterSense1
 
input: water_level
 
high_threshold: None
 
input_type: water_level
 
input_number: 0
 
high_threshold: 120
 
low_threshold: 50
 
deadband: 10
 
hysteresis: 10
 

	
 
[alert7]
 
name: "Water Temperature"
 
type: measurement
 
input_module: WaterSense1
 
input: water_temp
 
input_type: water_temp
 
input_number: 0
 
high_threshold: 30
 
low_threshold: 20
 
deadband: 10
 
\ No newline at end of file
 
hysteresis: 10
0 comments (0 inline, 0 general)