163 lines
5.7 KiB
Plaintext
163 lines
5.7 KiB
Plaintext
global_previous_state = {}
|
|
class GetStatus():
|
|
"""This class calculates the highest priority
|
|
alarm active for all parts of the source id. It scans the active alarms list,
|
|
splits each source id and returns the highest priority alarm to a dict object id_to_status.
|
|
It stores the previuos state of the dict object and compares current to previous.
|
|
ALARMST tags are then updated if they have been removed, added or the value changed
|
|
Args:
|
|
whid : Warehouse id for the project/ tag provider(string)
|
|
alarm_data: Current active alarms(dict)
|
|
KeyError: N/A"""
|
|
def __init__(self, whid, alarm_data):
|
|
self.whid = whid
|
|
self.alarm_data = alarm_data
|
|
self.id_to_status = {}
|
|
self.tag_provider = "[%s_SCADA_TAG_PROVIDER]" % (whid)
|
|
self.logger = system.util.getLogger("%s-Update-Visualisation" % (whid))
|
|
|
|
def update_status(self, item, priority):
|
|
if(self.id_to_status.get(item) is None or
|
|
self.id_to_status.get(item) < priority):
|
|
self.id_to_status[item] = priority
|
|
|
|
def build_status(self):
|
|
for k, v in self.alarm_data.items():
|
|
equipment, device, sub_device = "","",""
|
|
alarm_dict = v
|
|
source_id = alarm_dict.get("sourceId")
|
|
priority = alarm_dict.get("priority")
|
|
state = alarm_dict.get("state")
|
|
if state != 2:
|
|
id_elements = source_id.split("/")
|
|
controller = id_elements[0]
|
|
if len(id_elements) > 4:
|
|
self.logger.error("Incorrect length for source id")
|
|
else:
|
|
while True:
|
|
path = "/".join(id_elements)
|
|
self.update_status(path, priority)
|
|
id_elements.pop()
|
|
if len(id_elements) == 0:
|
|
break
|
|
global global_previous_state
|
|
self.calculate_diff()
|
|
global_previous_state = self.id_to_status
|
|
|
|
def build_alarm_paths_and_values(self, keys, paths, values):
|
|
for item in keys:
|
|
value = self.id_to_status.get(item)
|
|
tag_path = "%s%s/%s" % (self.tag_provider, item, "ALARMST")
|
|
paths.append(tag_path)
|
|
values.append(value)
|
|
return paths, values
|
|
|
|
def write_to_tags(self, message, paths, values):
|
|
system.tag.writeBlocking(paths, values)
|
|
self.logger.info(message + str(paths))
|
|
|
|
def calculate_diff(self):
|
|
set_previous_values = set(global_previous_state.keys())
|
|
set_current_values = set(self.id_to_status.keys())
|
|
intersect = set_current_values.intersection(set_previous_values)
|
|
removed_keys = set_previous_values - intersect
|
|
added_keys = set_current_values - intersect
|
|
changed_values = set(k for k in intersect if global_previous_state[k] != self.id_to_status[k])
|
|
tag_paths_to_delete = []
|
|
values_to_delete = []
|
|
for i in removed_keys:
|
|
tag_path = "%s%s/%s" % (self.tag_provider, i, "ALARMST")
|
|
tag_paths_to_delete.append(tag_path)
|
|
values_to_delete.append(0)
|
|
|
|
tag_paths_to_add, values_to_add = self.build_alarm_paths_and_values(added_keys, [], [])
|
|
for item in added_keys:
|
|
self.create_alarm_state_tags(self.tag_provider + item)
|
|
changed_tag_paths, changed_values = self.build_alarm_paths_and_values(changed_values, [], [])
|
|
|
|
if changed_tag_paths:
|
|
self.write_to_tags("Changed paths = ", changed_tag_paths, changed_values)
|
|
|
|
if tag_paths_to_add:
|
|
self.write_to_tags("Paths added = ", tag_paths_to_add, values_to_add)
|
|
|
|
if tag_paths_to_delete:
|
|
self.write_to_tags("Deleted paths = ", tag_paths_to_delete, values_to_delete)
|
|
|
|
def write_data(self):
|
|
status_encoded = system.util.jsonEncode(self.id_to_status)
|
|
system.tag.writeAsync([self.tag_provider
|
|
+ "System/IdToStatus"],
|
|
[status_encoded]
|
|
)
|
|
|
|
def create_alarm_state_tags(self, source_id):
|
|
if not system.tag.exists(source_id +"/ALARMST"):
|
|
tag = {"name": "ALARMST",
|
|
"valueSource": "memory",
|
|
"dataType": "Int1",
|
|
"value": 0}
|
|
create_tag = system.tag.configure(source_id, tag)
|
|
if not create_tag[0].isGood():
|
|
logger.warn("Failed to create tag: " + str(source_id))
|
|
|
|
def reset_tags(provider, query):
|
|
results = system.tag.query(provider, query)
|
|
tags_to_write = []
|
|
values_to_write = []
|
|
for i in results:
|
|
tags_to_write.append(str(i["fullPath"]))
|
|
values_to_write.append(0)
|
|
if tags_to_write:
|
|
system.tag.writeBlocking(tags_to_write, values_to_write)
|
|
|
|
def reset_alarms(whid):
|
|
logger_name = "%s-Alarm-Reset" % (whid)
|
|
logger = system.util.getLogger(logger_name)
|
|
logger.warn("Alarms have been reset")
|
|
provider = "%s_SCADA_TAG_PROVIDER" % (whid)
|
|
limit = 100
|
|
query = {
|
|
"options": {
|
|
"includeUdtMembers": True,
|
|
"includeUdtDefinitions": False
|
|
},
|
|
"condition": {
|
|
"path": "*ALARMST*",
|
|
"attributes": {
|
|
"values": [],
|
|
"requireAll": True
|
|
}
|
|
},
|
|
"returnProperties": [
|
|
"tagType",
|
|
"quality"
|
|
]
|
|
}
|
|
reset_tags(provider, query)
|
|
|
|
def reset_disconnects(whid):
|
|
logger_name = "%s-Disconnects-Reset" % (whid)
|
|
logger = system.util.getLogger(logger_name)
|
|
provider = "%s_SCADA_TAG_PROVIDER" % (whid)
|
|
limit = 100
|
|
query = {
|
|
"options": {
|
|
"includeUdtMembers": True,
|
|
"includeUdtDefinitions": False
|
|
},
|
|
"condition": {
|
|
"path": "*DCN*",
|
|
"attributes": {
|
|
"values": [],
|
|
"requireAll": True
|
|
}
|
|
},
|
|
"returnProperties": [
|
|
"tagType",
|
|
"quality"
|
|
]
|
|
}
|
|
reset_tags(provider, query)
|
|
logger.warn("DCN tags have been reset")
|