Hello Everyone,
I created this diagnostic tool that I’d love to share on the Ignition Exchange but I could use help optimizing it. I originally made this post a few month ago and here is the link with a detailed description of the concept.
[[Solved] Need help with system.tag.browse and diagnostic tool - Bit State Change Locator]
This tool is a “bit state change locator”. I use it to diagnose causes or effect within the system by using a selected state change’s timestamp chosen from an initial query result. A tag is selected and queried, a selectable list of “timestamps” and “value changed to” results are used to then recursively browse folders and query all tags at the selected timestamp (± a seconds buffer)
The tool works for me but I know it can be improved so any help or suggestions are appreciated. Here are my questions:
-
Using system.tag.queryTagHistory(), I iterate through a list of browse results and if a change in state occurred, the tag is read by system.tag.readBlocking() to gather the meta data to be displayed on the final results table. I query the tags one at a time because I don’t understand how the code would work if I load the entire list of browse results into the query. I can’t seem to parse through the results list unless I do it one at a time. The query as a result can be slow.
-
But is that a bad thing? Can a slow query ever be better on the system? I watched the database from the gateway and while this query happens, the database shows only 1 query happening at a time. Can this insure this diagnostic tool is not going to overload the system with too many queries?
-
And is there a way to show on the screen that this script is querying? It is hard to tell when the query is finished.
I have some more work to do this and I encourage ideas and suggestions for this tool.
Here is the code for the second button and thanks for reading.
CODE BEGINS:
#grab the "Power Table" dataset
tableData = event.source.parent.parent.getComponent('Power Table').data
selectedRow = event.source.parent.parent.getComponent('Power Table').selectedRow
#grab the time stamp from first column of the selected row from the dataset.
negBuffer = event.source.parent.getComponent('Spinner').intValue
posBuffer = event.source.parent.getComponent('Spinner 1').intValue
date = system.date.parse(tableData.getValueAt(selectedRow, 0))
#OPTION for manual timestamp input
#date = system.date.parse("2019-10-23 04:24:10")
#start and end date time buffer to create a time window to search.
sd = system.date.addSeconds(date, negBuffer)
ed = system.date.addSeconds(date, posBuffer)
#selects the folder to search through.
folder = event.source.parent.getComponent('Label').text
#browse through the chosen folder and queries every tag at the specified timestamp (+/- {x} second), creates oneRow, a row with 5 columns, for every flagged tag and appends each row to the list "rows".
tagPaths = []
def browse(path, filter):
results = system.tag.browse(path, filter)
for result in results.getResults():
if result['hasChildren'] == False:
tagPaths.append(result['fullPath'])
if result['hasChildren'] == True:
browse(result['fullPath'], filter)
browse(folder, {'dataType':'boolean', 'valueSource':'opc'})
tags = tagPaths
rows = []
for tag in tags:
check = system.tag.queryTagHistory(paths=[tag], calculations=['Count'], startDate=sd, endDate=ed)
#if a change in state is detected, append a new row with the tag path, the tag name, timestamp, value changed to, and documentation.
if check.rowCount >= 1:
for x in range(check.rowCount):
doc = system.tag.readBlocking([(tag.toString() + ".Documentation")])
name = system.tag.readBlocking([(tag.toString() + ".Name")])
oneRow = [tag.toString(), name[0].value, check.getValueAt(x,0), check.getValueAt(x,1), doc[0].value]
rows.append(oneRow)
#Create the headers and datset. Populate 'Power Table 1' with the dataset.
headers = ['Path', 'Name', 'Time Stamp', 'Value Changed To', 'Documentation']
data = system.dataset.toDataSet(headers, rows)
table = event.source.parent.parent.getComponent('Power Table 1')
table.data = data
event.source.parent.parent.getComponent('Power Table 1').data = data