Autoscaling Trends with Limits in OSIsoft PI ProcessBook
A practical guide to autoscaling trend axes in PI ProcessBook with defined limits, combining filter-based PI data queries and VBA scripting to keep your trends readable when outliers occur.
Roshan Soni
Autoscaling Trends with Limits in OSIsoft PI ProcessBook
Improving Trend Readability by Managing Outliers
When working with OSIsoft PI ProcessBook, it's common to use trends to visualize process data over time. However, if a tag or trace occasionally produces outlier values, the autoscale feature of trends can render your display unreadable—most data points become indistinguishable, compressed into a narrow range while the axis stretches to accommodate the extreme outlier.
A frequent request is to have an autoscaling trend within defined limits: if all trace values remain within a specified range (for example, -1500 to 1500), autoscale the display. But if even one value exceeds those bounds, switch to a fixed Y-axis scale. This approach keeps your trend readable and prevents faulty data from ruining the visualization.
In this blog post, we’ll walk through a practical implementation of this strategy in PI ProcessBook using VBA and PI-SDK, including tips for performance and extension to multiple traces.
The Challenge: When Autoscale Goes Bad
Consider a trend configured to autoscale. For most of its data, your process tags inhabit a normal band. But if a sensor fault, communication glitch, or rare excursion drives a point far outside this range, the autoscale algorithm stretches to display everything. Your regular signal trends collapse into an unreadable flat line at the bottom or middle of the display, making it impossible to interpret normal behavior.
The Goal: Autoscale Within Limits
We want our ProcessBook trend to autoscale automatically only if all trace values stay inside a sensible range (say, -1500 < value < 1500). If any tag pops outside that window—even just one point—the trend should instead use a fixed (manual) scale of -1500 to +1500. Essentially:
- All values in range ⇒ Autoscale
- Any value out of range ⇒ Fixed scale
The Solution: Efficiently Checking PI Data
The naive approach is to iterate through every value on every trace in the trend, checking for out-of-bounds values. This works, but it can be slow—especially with multiple traces or frequent data updates. If you try this in ProcessBook VBA, you may notice lockup or sluggishness.
A better method leverages the PI-SDK’s RecordedValues method with a filter expression. This allows you to ask the PI Server directly: “Give me only the values outside my limits in this time range.” If none are returned, you know all values are in bounds, and you can safely autoscale.
Sample Code: Autoscaling with Limits in VBA
Below is a summarized, production-ready example adapted for PI ProcessBook. It loops through all traces, checks each for out-of-range values over the visible time range, and sets the trend scale accordingly. It also throttles how often scale changes (once per minute) to avoid overloading the PI Server.
Dim dtLastScaleReset As Date
Sub UpdateScale()
Const Min = -1500
Const Max = 1500
Dim i As Long
Dim myServer As Server
Dim myPIPoint As PIPoint
Dim myPIData As PIData
Dim myPIValues As PIValues
Dim TagName As String
Dim NodeName As String
Dim st As New PITimeFormat
Dim et As New PITimeFormat
Dim bAuto As Boolean
bAuto = True
If Trend1.TraceCount > 0 Then
For i = 1 To Trend1.TraceCount
TagName = ParseTagName(Trend1.GetTagName(i))
NodeName = ParseNodeName(Trend1.GetTagName(i))
st.InputString = Trend1.StartTime
et.InputString = Trend1.EndTime
Set myServer = PISDK.Servers(NodeName)
Set myPIPoint = myServer.PIPoints(TagName)
Set myPIData = myPIPoint.Data
' Retrieve any values outside limits
Set myPIValues = myPIData.RecordedValues(st, et, btInside, _
"'" & TagName & "' > " & CStr(Max) & " or '" & TagName & "' < " & CStr(Min), fvRemoveFiltered)
If myPIValues.Count > 0 Then
bAuto = False
Exit For
End If
Next i
End If
If bAuto Then
Trend1.SetTraceScale "Autorange", "Autorange"
Else
Trend1.SetTraceScale Min, Max
End If
End Sub
Function ParseTagName(FullTagPath As String) As String
Dim SearchChar As String, MyPos As Integer
SearchChar = "\"
MyPos = InStr(3, FullTagPath, SearchChar, vbTextCompare)
ParseTagName = Right$(FullTagPath, Len(FullTagPath) - MyPos)
End Function
Function ParseNodeName(FullTagPath As String) As String
Dim SearchChar As String, MyPos As Integer
SearchChar = "\"
MyPos = InStr(3, FullTagPath, SearchChar, vbTextCompare)
ParseNodeName = Mid(FullTagPath, 3, MyPos - 3)
End Function
Private Sub Trend1_DataUpdate(ByVal ntrace As Integer)
If DateDiff("n", dtLastScaleReset, Now) >= 1 Then
UpdateScale
dtLastScaleReset = Now()
End If
End Sub
Private Sub Display_Open()
dtLastScaleReset = Now()
End Sub
Design Highlights
- Efficient Data Checking: Calls to
RecordedValueswith a filter mean only out-of-range values are pulled from the server, which is much faster than downloading all data points. - Works with Multiple Traces: Loops through each trend trace; autoscale is only allowed if all are in range.
- Throttled Updates: Timer logic (
dtLastScaleReset) ensures the code only checks for outliers (and potentially readjusts trend axes) once per minute. - Reusable Parsing Functions: Tag and node name parsing makes it easy to reuse across trends with network naming.
Conclusion
Using autoscaling with explicit limits in PI ProcessBook dramatically improves the usability of trends when outliers can occur. By combining efficient filter-based queries with a logical structure, you keep your displays readable and performant—even with multiple, frequently updating traces.
Let us know in the comments: have you solved a similar trend-scaling challenge in PI? What approaches have you used?
Further Reading:
Special thanks to community contributors for sample code and insights!
Tags
About Roshan Soni
Expert in PI System implementation, industrial automation, and data management. Passionate about helping organizations maximize the value of their process data through innovative solutions and best practices.
No comments yet
Be the first to share your thoughts on this article.
Related Articles
Enhancing PI ProcessBook Trends with Banding and Zones: User Needs, Workarounds, and the Road Ahead
A look at the user demand for trend banding/zoning in OSIsoft PI ProcessBook, current VBA workarounds, UI challenges, and how future PI Vision releases aim to address these visualization needs.
Roshan Soni
Migrating PIAdvCalcFilVal Uptime Calculations from PI DataLink to PI OLEDB
Learn how to translate PI DataLink's PIAdvCalcFilVal advanced calculations—like counting uptime based on conditions—into efficient PI OLEDB SQL queries. Explore three practical approaches using PIAVG, PIINTERP, and PICOunt tables, and get tips for validation and accuracy.
Roshan Soni
Understanding PI Web API WebID Encoding: Can You Generate WebIDs Client-Side?
Curious about how PI Web API generates WebIDs and whether you can encode them client-side using GUIDs or paths? This article explores the encoding mechanisms, current documentation, and best practices for handling WebIDs in your applications.
Roshan Soni