Overlaying non-associated Alarms on Trends

We recently had an issue at a site with an oven burner. I was looking at a trend with some oven temperatures etc on it, and also noticed in the alarm journal some alarms for the gas valves. I thought to get a good timeline it would be nice if I could somehow overlay those alarms on the trends of the oven temperatures.

If we were storing the tag history for the alarm I could add it to the trend, but since it's already stored in the alarm journal it seems redundant.

I tried searching in the forum and came across this post: Alarm Trend Tag Override Suggestion - #4 by amarks

As I understand it that value trend can show you your analog alarms overlayed on your analog historical trend.

That looks like the general idea I'm trying to achieve, but I have a digital alarm that isn't directly related to the analog values I'm trending, and would like to somehow plot it on the trend.

Is there anyway to do this? Or would my only option be to store the digital alarm tag values with Historian as well as with an Alarm?

As an SI we deal with multiple sites, this one specifically is using Vision, but we have other using Perspective as well, and would be curious to hear solutions that could work in either situation.

You tagged this post for both Perspective and Vision. In Vision, my NoteChart module enhances the EasyChart component and the Classic Chart component (with time series data) to display any kind of time-stamped event data as labeled stroke marks at the right points on the chart. They are interactive, and produce X-Trace displays at the precise timestamp when clicked.

Hi Phil,

I tagged both Vision and Perspective, because while this specific site is using Vision, I was curious about solutions for either situation.

I did a quick glance at your NoteChart module, and it looks like it could possibly be the kind of thing I'm looking for. I managed to find what I needed to without this, but it could be useful going forward. I'll try to take a closer look into it when I have a bit more time.

Does that mean this problem has been solved with regard to the Vision question? If so, what did you find?

1 Like

Sorry about that, I guess my comment wasn't very specific.

When I said "I managed to find what I need", I meant I managed to track down and solve the issue I was looking into with the oven, despite not having a way to overlay the digital alarms on the oven temperature trend.

Phil's NoteChart, does look like it can do what I wanted (although I haven't tried), but we didn't have it when I was troubleshooting the issue. Right now I don't think the customer is willing to buy it either, because it's not something they need normally, it just would have made tracking down this issue easier.

I have not found any other way to do it, either in Vision, or Perspective, but I haven't spent a lot of time looking after I solved the issue at hand.

If you're just wanting a visual reference when a tag was in an alarmed state, I imagine the simplest solution would be to place some value and interval markers on the easy chart.

Example:
• Add a button to the window, and give it two custom properties: alarmPath and journalData
image

• Perform a journal query from the button's action performed event handler using the easyChart's start and end date as well as the button's alarmPath property to filter the data:

easyChart = event.source.parent.getComponent('Easy Chart')
startDate = easyChart.startDate
endDate = easyChart.endDate
alarmPath = event.source.alarmPath
def getJournalData(start = startDate, end = endDate, alarm = alarmPath):
	journalData = system.alarm.queryJournal(journal = 'Journal', startDate = start, endDate = end, path = alarm).dataset
	def setJournalData():
		event.source.journalData = journalData
	system.util.invokeLater(setJournalData)
system.util.invokeAsynchronous(getJournalData)

• Create a couple of custom methods [or library scripts] for adding markers to the chart's plot:

addIntervalMarker custom method

#def addIntervalMarker(self, startDate, endDate):
	from org.jfree.chart.plot import IntervalMarker
	faultColor = system.gui.color(255, 0, 0, 100)
	plot = self.parent.getComponent('Easy Chart').getComponent(0).getComponent(0).chart.plot
	plot.addDomainMarker(IntervalMarker(system.date.toMillis(startDate), system.date.toMillis(endDate), faultColor))

addValueMarker custom method

#def addValueMarker(self, date):
	from org.jfree.chart.plot import ValueMarker
	from java.awt import BasicStroke
	chartX = system.date.toMillis(date)
	plot = self.parent.getComponent('Easy Chart').getComponent(0).getComponent(0).chart.plot
	faultColor = system.gui.color('red')
	valueMarker = ValueMarker(chartX)
	valueMarker.setStroke(BasicStroke(3))
	valueMarker.setPaint(faultColor)
	plot.addDomainMarker(valueMarker)

• Finally, add the markers to the chart using the journalData property change event in the propertyChange event handler:

if event.propertyName == 'journalData':
	easyChart = event.source.parent.getComponent('Easy Chart')
	
	# Reset existing domain markers
	plot = easyChart.getComponent(0).getComponent(0).chart.plot
	plot.clearDomainMarkers()
	
	# Locate all the active to not active intervals,
	# and put the start and end of each in a list
	journalData = event.newValue
	intervalList = []
	currentStartDate = None
	for row in xrange(journalData.rowCount):
		eventTime = journalData.getValueAt(row, 'EventTime')
		eventState = journalData.getValueAt(row, 'EventState')
		if eventState > 1 and not currentStartDate:
			currentStartDate = eventTime
		elif eventState < 2 and currentStartDate is not None:
			intervalList.append([currentStartDate, eventTime])
			currentStartDate = None
	
	# If the last entry is alarmed, extend the alarm to the end of the chart
	if currentStartDate:
		intervalList.append([currentStartDate, easyChart.endDate])
	
	# Iterate through the intervals and mark the chart
	for interval in intervalList:
		alarmStart, alarmEnd = interval
		event.source.addIntervalMarker(alarmStart, alarmEnd)
		event.source.addValueMarker(alarmStart)
		event.source.addValueMarker(alarmEnd)

Result:

Edit: Improved interval segmenting logic

2 Likes

That looks like exactly the kind of thing I was after. I'll have to take a closer look and play around with it a bit. Could be useful going forward.

1 Like