Added alerts and removed unmarshalling

This commit is contained in:
2020-01-30 17:02:54 -06:00
parent 3bb2fdfad6
commit 5f045ccc8d
3 changed files with 40 additions and 73 deletions

View File

@@ -5,18 +5,19 @@ from pycomm.ab_comm.clx import Driver as clx
from pycomm.cip.cip_base import CommError, DataError from pycomm.cip.cip_base import CommError, DataError
class DataPoint(object): class DataPoint(object):
def __init__(self,changeThreshold=0,guaranteed=3600, name="datapoint",alertThreshold=[],alertCondition=[],alertResponse=[],alertContact=[]): def __init__(self,changeThreshold=0,guaranteed=3600, name="datapoint",alertThreshold=[],alertCondition=[],alertResponse=[],alertContact=[], alertName=[]):
self.value = None self.value = None
self.lastvalue = None self.lastvalue = None
self.lastsend = 0 self.lastsend = 0
self.changeThreshold = changeThreshold self.changeThreshold = changeThreshold
self.guaranteed = guaranteed self.guaranteed = guaranteed
self.name = name self.name = name
self.alerted = False
self.alertThreshold = alertThreshold self.alertThreshold = alertThreshold
self.alertCondition = alertCondition self.alertCondition = alertCondition
self.alertResponse = alertResponse self.alertResponse = alertResponse
self.alertContact = alertContact self.alertContact = alertContact
self.alertName = alertName
self.alerted = [False] * len(self.alertThreshold)
def checkSend(self,value): def checkSend(self,value):
@@ -37,8 +38,8 @@ class DataPoint(object):
"not": "value != threshold" "not": "value != threshold"
} }
for thres,cond in zip(self.alertThreshold,self.alertCondition): """for thres,cond,name,contact,alerted in zip(self.alertThreshold,self.alertCondition, self.alertName, self.alertContact,self.alerted):
#check value for alert threshold #check value for alert threshold send back first alarmed value
evalVars = { evalVars = {
"value": value, "value": value,
"threshold": thres "threshold": thres
@@ -47,12 +48,32 @@ class DataPoint(object):
if func == None: if func == None:
print("Not an available function: {}".format(cond)) print("Not an available function: {}".format(cond))
else: else:
if eval(func, evalVars): if eval(func, evalVars) and not alerted:
return {"message":"Read value for {} is {} threshold value {}".format(self.name,value,thres)}
return {"alert": name}
else: else:
self.alerted = False self.alerted = False
return None 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]
}
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
return None
class modbusDataPoint(DataPoint): class modbusDataPoint(DataPoint):
def __init__(self,changeThreshold,guaranteed,name,register=1,baud=19200,stopBits=1,parity=None, device='/dev/ttyS0'): def __init__(self,changeThreshold,guaranteed,name,register=1,baud=19200,stopBits=1,parity=None, device='/dev/ttyS0'):
@@ -69,8 +90,8 @@ class modbusDataPoint(DataPoint):
pass pass
class plcDataPoint(DataPoint): class plcDataPoint(DataPoint):
def __init__(self,changeThreshold,guaranteed,name,plcIP='192.168.1.10',plcType='Micro800',tag=None,alertThreshold=[],alertCondition=[],alertResponse=[],alertContact=[]): 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) DataPoint.__init__(self,changeThreshold,guaranteed,name,alertThreshold,alertCondition,alertResponse,alertContact,alertName)
self.plcIP = plcIP self.plcIP = plcIP
self.plcType = plcType self.plcType = plcType
self.tag = tag self.tag = tag

View File

@@ -23,7 +23,6 @@ def run(config, device, port, host, rootCAPath):
console_out.setFormatter(log_formatter) console_out.setFormatter(log_formatter)
filelogger.addHandler(console_out) filelogger.addHandler(console_out)
filelogger.info("IN Driver")
filelogger.info("Got Config: \n{}".format(config)) filelogger.info("Got Config: \n{}".format(config))
#Extract data from passed in config #Extract data from passed in config
@@ -75,7 +74,8 @@ def run(config, device, port, host, rootCAPath):
condition = config['PLCData'][key]["alert"]["condition"] condition = config['PLCData'][key]["alert"]["condition"]
response = config['PLCData'][key]["alert"]["response"] response = config['PLCData'][key]["alert"]["response"]
contact = config['PLCData'][key]["alert"]["contact"] contact = config['PLCData'][key]["alert"]["contact"]
datapoint = plcDataPoint(changeThreshold,guaranteed,str(name),plcIP=str(plcIP),plcType=str(plcType),tag=str(tag),alertThreshold=threshold,alertCondition=condition,alertResponse=response,alertContact=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)
else: else:
datapoint = plcDataPoint(changeThreshold,guaranteed,str(name),plcIP=str(plcIP),plcType=str(plcType),tag=str(tag)) datapoint = plcDataPoint(changeThreshold,guaranteed,str(name),plcIP=str(plcIP),plcType=str(plcType),tag=str(tag))
datapoints.append(datapoint) datapoints.append(datapoint)
@@ -88,18 +88,18 @@ def run(config, device, port, host, rootCAPath):
pass pass
#build alert points #A function for polling data and checking alert status per datapoint.
#A function for polling general data can be latent no greater than a min between polls #Latency should remain low on polls but manage thresholds for how often to send data
#loop through list of data points to read and check value changes #Loop through list of data points to read value, check send thresholds, and check alert thresholds
#sleep for 30 secs
def dataCollection(): def dataCollection():
while True: while True:
message = {} message = {}
for datapoint in datapoints: for datapoint in datapoints:
val,alertMessage = datapoint.read() val,alertMessage = datapoint.read()
if alertMessage != None and not datapoint.alerted : if alertMessage != None:
alertMessage["location"] = locationID
filelogger.info("Publishin: {}\nTo Topic: {}".format(alertMessage,alm_topic))
myAWSIoTMQTTClient.publish(alm_topic,json.dumps(alertMessage),1) myAWSIoTMQTTClient.publish(alm_topic,json.dumps(alertMessage),1)
datapoint.alerted =True
if datapoint.checkSend(val): if datapoint.checkSend(val):
message[datapoint.name] = val message[datapoint.name] = val
if message: if message:
@@ -108,19 +108,6 @@ def run(config, device, port, host, rootCAPath):
myAWSIoTMQTTClient.publish(dt_topic, json.dumps(message),1) myAWSIoTMQTTClient.publish(dt_topic, json.dumps(message),1)
time.sleep(5) time.sleep(5)
#A function for polling alert data should be very near real time
#if plcdata != to empty then setup polls for tags
#use ping and reads as watchdog values for connectivity
#if modbusdata != to empty then setup polls for registers
#use reads as watchdog values for connectivity
#if currentdata != to empty then setup polls for current
#if raw current value > 3.5 then current is good else current disconnected
#if voltagedata != to empty then setup polls for voltage
#if raw voltage value > 0 then voltage is good else voltage disconnected
#sleep for 1 secs
def alertCollection():
pass
#Start a thread for data and a thread for alerts
# list of all threads, so that they can be killed afterwards # list of all threads, so that they can be killed afterwards
@@ -130,10 +117,6 @@ def run(config, device, port, host, rootCAPath):
data_thread.start() data_thread.start()
all_threads.append(data_thread) all_threads.append(data_thread)
alert_thread = threading.Thread(target=alertCollection, args=(), name="Thread-alerts")
alert_thread.start()
all_threads.append(alert_thread)
for thread in all_threads: for thread in all_threads:

View File

@@ -1,37 +0,0 @@
def unmarshal_dynamodb_json(node):
data = dict({})
data['M'] = node
return _unmarshal_value(data)
def _unmarshal_value(node):
if type(node) is not dict:
return node
for key, value in node.items():
key = key.lower()
if key == 'bool':
return value
if key == 'null':
return None
if key == 's':
return value
if key == 'n':
if '.' in str(value):
return float(value)
return int(value)
if key in ['m', 'l']:
if key == 'm':
data = {}
for key1, value1 in value.items():
if key1.lower() == 'l':
data = [_unmarshal_value(n) for n in value1]
else:
if type(value1) is not dict:
return _unmarshal_value(value)
data[key1] = _unmarshal_value(value1)
return data
data = []
for item in value:
data.append(_unmarshal_value(item))
return data