Added alert buffers and reminders
This commit is contained in:
@@ -5,7 +5,7 @@ from pycomm.ab_comm.clx import Driver as clx
|
||||
from pycomm.cip.cip_base import CommError, DataError
|
||||
|
||||
class DataPoint(object):
|
||||
def __init__(self,changeThreshold=0,guaranteed=3600, name="datapoint",alertThreshold=[],alertCondition=[],alertResponse=[],alertContact=[], alertName=[]):
|
||||
def __init__(self,changeThreshold=0,guaranteed=3600, name="datapoint",alertThreshold=[],alertCondition=[],alertResponse=[],alertContact=[], alertName=[],alertBuffer=[],alertReminder=[]):
|
||||
self.value = None
|
||||
self.lastvalue = None
|
||||
self.lastsend = 0
|
||||
@@ -17,7 +17,11 @@ class DataPoint(object):
|
||||
self.alertResponse = alertResponse
|
||||
self.alertContact = alertContact
|
||||
self.alertName = alertName
|
||||
self.alerted = [False] * len(self.alertThreshold)
|
||||
self.alertBuffer = alertBuffer
|
||||
self.alertReminder = alertReminder
|
||||
self.alerted = [False] * len(self.alertCondition)
|
||||
self.reminderTimer = [0] * len(self.alertCondition)
|
||||
self.alertTimer = [0] * len(self.alertCondition)
|
||||
|
||||
|
||||
def checkSend(self,value):
|
||||
@@ -35,44 +39,53 @@ class DataPoint(object):
|
||||
"eq": "value == threshold",
|
||||
"gte": "value >= threshold",
|
||||
"lte": "value <= threshold",
|
||||
"not": "value != threshold"
|
||||
"not": "value != threshold",
|
||||
|
||||
}
|
||||
|
||||
oppositeConditions = {
|
||||
"gt": "lt",
|
||||
"lt": "gt",
|
||||
"gte": "lte",
|
||||
"lte": "gte",
|
||||
"eq": "not",
|
||||
"not": "eq"
|
||||
}
|
||||
|
||||
"""for thres,cond,name,contact,alerted in zip(self.alertThreshold,self.alertCondition, self.alertName, self.alertContact,self.alerted):
|
||||
#check value for alert threshold send back first alarmed value
|
||||
evalVars = {
|
||||
"value": value,
|
||||
"threshold": thres
|
||||
}
|
||||
func = conditions.get(cond)
|
||||
if func == None:
|
||||
print("Not an available function: {}".format(cond))
|
||||
else:
|
||||
if eval(func, evalVars) and not alerted:
|
||||
|
||||
return {"alert": name}
|
||||
else:
|
||||
self.alerted = False
|
||||
return None
|
||||
"""
|
||||
for x in range(len(self.alerted)):
|
||||
#check value for alert threshold send back first alarmed value
|
||||
evalVars = {
|
||||
"value": value,
|
||||
"threshold": self.alertThreshold[x]
|
||||
"threshold": self.alertThreshold[x][0]
|
||||
}
|
||||
func = conditions.get(self.alertCondition[x])
|
||||
if func == None:
|
||||
print("Not an available function: {}".format(self.alertCondition[x]))
|
||||
else:
|
||||
result = eval(func,evalVars)
|
||||
if result and not self.alerted[x]:
|
||||
self.alerted[x] = True
|
||||
return {"alert": self.alertName[x], "contact": self.alertContact[x]}
|
||||
elif result and self.alerted[x]:
|
||||
pass
|
||||
else:
|
||||
self.alerted[x] = False
|
||||
if result and not self.alerted[x]:#threshold crossed but not already alerted
|
||||
if self.alertTimer[x] != 0 and time.time() - self.alertTimer[x] > self.alertBuffer[x]:#timer started and crossed threshold
|
||||
self.alerted[x] = True
|
||||
self.alertTimer[x] = 0
|
||||
self.reminderTimer[x] = time.time()
|
||||
return {"alert": self.alertName[x] + " alarm", "contact": self.alertContact[x], "response": self.alertResponse[x]}
|
||||
elif self.alertTimer[x] == 0:#timer not started yet
|
||||
self.alertTimer[x] = time.time()
|
||||
elif result and self.alerted[x]:#threshold crossed and already on alert
|
||||
if self.alertReminder[x] and time.time() - self.reminderTimer[x] > self.alertReminder[x]: #reminder threshold crossed
|
||||
self.reminderTimer[x] = time.time()
|
||||
return {"alert": self.alertName[x] + " reminder", "contact": self.alertContact[x], "response": self.alertResponse[x]}
|
||||
elif not result and self.alerted[x]:#threshold not crossed but previously alerted
|
||||
evalVars["threshold"] = self.alertThreshold[x][1]
|
||||
func = conditions.get(oppositeConditions.get(self.alertCondition[x]))
|
||||
if eval(func,evalVars):#untrigger threshold crossed
|
||||
if self.alertTimer[x] != 0 and time.time() - self.alertTimer[x] > self.alertBuffer[x]:#timer started and crossed threshold
|
||||
self.alerted[x] = False
|
||||
self.alertTimer[x] = 0
|
||||
#Send cleared alarm message
|
||||
return {"alert": self.alertName[x] + " alarmed cleared", "contact": self.alertContact[x], "response": self.alertResponse[x]}
|
||||
elif self.alertTimer[x] == 0:#timer not started
|
||||
self.alertTimer[x] = time.time()
|
||||
return None
|
||||
|
||||
class modbusDataPoint(DataPoint):
|
||||
@@ -90,8 +103,8 @@ class modbusDataPoint(DataPoint):
|
||||
pass
|
||||
|
||||
class plcDataPoint(DataPoint):
|
||||
def __init__(self,changeThreshold,guaranteed,name,plcIP='192.168.1.10',plcType='Micro800',tag=None,alertThreshold=[],alertCondition=[],alertResponse=[],alertContact=[], alertName=[]):
|
||||
DataPoint.__init__(self,changeThreshold,guaranteed,name,alertThreshold,alertCondition,alertResponse,alertContact,alertName)
|
||||
def __init__(self,changeThreshold,guaranteed,name,plcIP='192.168.1.10',plcType='Micro800',tag=None,alertThreshold=[],alertCondition=[],alertResponse=[],alertContact=[], alertName=[],alertBuffer=[],alertReminder=[]):
|
||||
DataPoint.__init__(self,changeThreshold,guaranteed,name,alertThreshold,alertCondition,alertResponse,alertContact,alertName,alertBuffer,alertReminder)
|
||||
self.plcIP = plcIP
|
||||
self.plcType = plcType
|
||||
self.tag = tag
|
||||
@@ -112,7 +125,7 @@ class plcDataPoint(DataPoint):
|
||||
except CommError as cerr:
|
||||
print("Error: {}".format(cerr))
|
||||
|
||||
return False
|
||||
return False, None
|
||||
|
||||
def write(self):
|
||||
pass
|
||||
|
||||
@@ -75,7 +75,9 @@ def run(config, device, port, host, rootCAPath):
|
||||
response = config['PLCData'][key]["alert"]["response"]
|
||||
contact = config['PLCData'][key]["alert"]["contact"]
|
||||
alertName = config['PLCData'][key]["alert"]["name"]
|
||||
datapoint = plcDataPoint(changeThreshold,guaranteed,str(name),plcIP=str(plcIP),plcType=str(plcType),tag=str(tag),alertThreshold=threshold,alertCondition=condition,alertResponse=response,alertContact=contact, alertName=alertName)
|
||||
buffer = config['PLCData'][key]["alert"]["buffer"]
|
||||
reminder = config['PLCData'][key]["alert"]["reminder"]
|
||||
datapoint = plcDataPoint(changeThreshold,guaranteed,str(name),plcIP=str(plcIP),plcType=str(plcType),tag=str(tag),alertThreshold=threshold,alertCondition=condition,alertResponse=response,alertContact=contact, alertName=alertName,alertBuffer=buffer,alertReminder=reminder)
|
||||
else:
|
||||
datapoint = plcDataPoint(changeThreshold,guaranteed,str(name),plcIP=str(plcIP),plcType=str(plcType),tag=str(tag))
|
||||
datapoints.append(datapoint)
|
||||
@@ -98,13 +100,14 @@ def run(config, device, port, host, rootCAPath):
|
||||
val,alertMessage = datapoint.read()
|
||||
if alertMessage != None:
|
||||
alertMessage["location"] = locationID
|
||||
filelogger.info("Publishin: {}\nTo Topic: {}".format(alertMessage,alm_topic))
|
||||
alertMessage["timestamp"] = datetime.now().isoformat()
|
||||
filelogger.info("Publishing: {}\tTo Topic: {}".format(alertMessage,alm_topic))
|
||||
myAWSIoTMQTTClient.publish(alm_topic,json.dumps(alertMessage),1)
|
||||
if datapoint.checkSend(val):
|
||||
message[datapoint.name] = val
|
||||
if message:
|
||||
message["timestamp"] = datetime.now().isoformat()
|
||||
filelogger.info("Publishing: {}\nTo Topic: {}".format(message,dt_topic))
|
||||
filelogger.info("Publishing: {}\tTo Topic: {}".format(message,dt_topic))
|
||||
myAWSIoTMQTTClient.publish(dt_topic, json.dumps(message),1)
|
||||
time.sleep(5)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user