Add more advanced string handling functions to the String Builder data reference
I would like to use some more advanced string functions such as Split, Len (string length), and even regex filtering to allow more fine grained control of how some input strings (such as attribute values or substitution parameters) are manipulated to create a new string output.
I rally want the ability to do more advanced String operations in String builder.
Since the PI system is not only a analysis tool, it is also a foundation to store asset information.
In response to Jagdish Konathala, "Thanks Steve. We had issues upgrading to..."
Yes, SP2a does fix the installation issue with SQL Server AlwaysOn Availability groups.
In response to Stephen Kwan, "AF 2018 SP2a has a new feature for split..."
Thanks Steve. We had issues upgrading to AF 2018 SP2 since we use SQL AlwaysOn groups. Hopefully that is fixed in SP2a. Will upgrade and test the split functionality. The workaround we employed is convoluted, thanks for the split feature!
In response to Stephen Kwan, "AF 2018 SP2a has a new feature for split..."
That's a great step for Analytics, and I'll have to have a look at how it works. Would still like to see this in the StringBuilder DR as well, given the way this DR is often used for dynamically generating a tag name to be used in the PI Point DR.
AF 2018 SP2a has a new feature for splitting strings. Please see release note:
144299 - Split function was added to Expression and Event Frame Generation analyses to split a string into a string array.
Splitting on a separator (.,-) could help with separating a string. Split('MyText.YourText', '.') => 'MyText'. Will this be possible?
In response to Chris Beaupre, "A String Length and Basic Delimiter func..."
Can you help me understand what you're trying to do with tabular alarm data? As you know, an AF data reference such as the string builder is only executed on demand by the client. In order to have a fruitful discussion, it would be great if we can get some details on your use cases.
Chris Beaupre commented
A String Length and Basic Delimiter function needs to be part of the core string builder functionality. This would solve a lot of issues with handling tabular alarm data.
I may have discovered a side effect using the analysis to populate an event frame with the formatted value. Each time the EF creates a child, it appears that PI re-executes the analysis. If both the raw numeric value and the formatted string are stored in the EF, they may be different.
I have an analysis that executes every 15 minutes. It stores the raw numeric data and the formatted string in separate AF attributes. I have a second event triggered analysis that creates an event frame if the raw numeric value exceeds it's Hi Limit. The EF contains the raw numeric value as it was when the original EF was created but the formatted string contains the current value.
The ability to format the string in String Builder would eliminate the need for two attributes and this potential discrepancy.
Using the string builder interface is confusing. The best method that I've found is to click the right arrow ">", look for the function, reference, etc. that I need and then type it in on another line. I've worked with at least two support engineers that have had similar problems when helping me via a Bomgar session.
We would like to see a format string that formats a number to a string and inserts commas in the appropriate positions. Example number 9999999 formats to 9,999,999
along with decimals, currency, etc. Our primary use is when data from an event frame is included in a notification.
String builder could also be used to read the data from the PI Archive and format it into the Event Frame attributes as a string.
John Hosmer commented
Additionally, in case 00563064 we are attempting to format integers with comma thousand separators (123456789 --> 123,456,789). This is not possible with the current string builder function support (2018 SP1).
Introducing the Len() PE function among other functions that have been suggested so far would enable users to format strings of variable length.
See Support case 960088; trying to create a reference to a child attribute in another branch in an AF template. That attribute value is static content.
I would love to see a basic if/then/else function added to String Builder. In some cases, I can work around it using Replace or other functions, but I have had to abandon dozens of attempts where I want a string attribute to depend on some other attribute's value, and found it impossible. An IF function would have been perfect each time.
Just to add to this, another use case is to get the root element of the current element path (as opposed to the parent element).
As an example, I can create an attribute "SitePath" with %ElementPath% and it will get me a value as something like below:
To get the 2nd element from the root (i.e. "Element1.1"), I would have to do this in Analytics with the combination of following functions:
Which is not possible with String Builder.
(Unless there is already a substitution parameter to get me the element FROM the top down, instead from the bottom up)
Luke Yarnall commented
An additional capability that would be good is the ability to parse a string by delimiters. This would be helpful when tracking alarms and events from the Interface for OPC AE. OPC AE messages are sent as a pipe (|) delimited string and stored as string PI tags.
For alarm and event tracking with event frames, it is useful to split the pipe delimited string and store each alarm attribute as an AF child attribute.
Currently this must be done in asset analytics using the InStr function, which is not available in String Builder.
I've attached a relevant tech support case to this enhancement request.
In response to Stephen Kwan, "John, What are you trying to do? Are yo..."
That wasn't my original use case, but these would probably be easier to parse with some of these kind of functions. I'm more looking at parsing various string elements for PI tag name resolution - some of my customers (and one in particular where I have a couple of current projects) use some very nicely consistent naming conventions, and being able to dynamically resolve tag names from asset string data would be easier with some of these functions.
In response to John Messinger, "Hi David, Some of the additional funct..."
What are you trying to do? Are you parsing alarms and events?
In response to David Moler, "We are evaluating what features we shoul..."
Some of the additional functionality I would like to see includes the following standard .Net String methods:
Clone()Insert()LengthPadLeft() & PadRight()Remove()Split()
I'd also like to see the following string methods from Analyses as additional functionality in the StringBuilder:
Char()Len() - pretty much same as above Length() function
I also agree with Kevin Fisk that being able to use substitution parameters in all the arguments of the Replace() function would be useful.
Not covered in the above two lists is an IsNumeric() method. More on this later.
Also, it would be great if some regex functionality could be included, where I can extract a specific matching substring from a larger string based on a regular expression.
Lastly, a simple If..Then..Else function to be able able to make a decision on how to extract part of a string would be really useful. For example, I might like to extract a substring at the beginning or end of another string, but only the numeric component (or maybe only the non-numeric component). An example of the envisioned usage would be:
If IsNumeric(Right(%Element%, 3)) Then Right(%Element%, 3) Else Right(%Element%, 2)
This is particularly useful when dealing with assets that are alphanumerically named with the number at the end of the string (such as one of our customer's gas wells) and we want to extract either the numeric or non-numeric component from a well that may have either two or three numbers at the end (ie, Well99 or Well208).
AdminDavid Moler (Admin, OSIsoft) commented
We are evaluating what features we should prioritize for StringBuilder. We want to make sure that we are addressing use cases that are current pain points. Would anyone interested in this feature be willing to share (here or over email) examples? Specifically we are looking for:
* Input sources and example values (e.g. %Element% is "Well 123" or 'attribute' is "Active")
* The logic that needs to be applied to those inputs and the expected output (based on the example inputs)